 !L!$:0(  @ #P(P> @"@&0(  0 )P%AI @ "  / 
MY&,"       !  G       $ "<       0 )P      !  G A&D"  (  \ 0
M:@( D&D"  (  \"<:0(       (  \"H:0(         !L"P:0(  @ #P+QI
M @#\,@$  @ #P/1? 0#(:0(  @ #P-1I @         &P-QI @ "  / W$("
M .AI @ $  3 "&H" /QI @ B  # D-L   4 !<!A<G)A>0    $ "<#TVP  
M @ #P!QJ @         &P"1J @ "  / ,&H" -07 @ "  / 2/,! *P: @ !
M  G       $ "<       0 )P      !  G 7&H"  (  \!T:@( :&H"  ( 
M \"L,@(       (  \" :@(         !L"(:@(  @ #P)1J @!X3 (  @ #
MP#3M 0 ,( (  0 )P      !  G       $of the command (on departmental M/C's) is -
!
! EDWIN.PROOF  <input> / CODE , LIST
!
! CODE is CIF code which can be viewed.
! LIST is the listing of the mode changes and plotting inst. given.
! Any faults found in the input are reported on the control stream,
! ie. the users console. A fault may be one of three types.   First
! it may be a 'WARNING', these are given for the users convenience,
! and usualy refer to a feature which depends on the plotter model,
! the input is still accepted as being valid to plot.    The second
! alternative is 'FAULT',  where  the input does not conform to the
! allowed syntax.  This fault is general through out the range. The
! final type of fault is a 'DISASTER',  which causes the program to
! stop prematurely.
! The input should be in binary to allow the programme to see the
! full character set on the tape.
!
!
!
%BEGIN
!
!
!
!*****************************************************************
!*                                                               *
!*                                                               *
!*       DECLARATION  OF  GLOBAL  VARIABLES  SECTION             *
!*                                                               *
!*                                                               *
!*****************************************************************
!
!
%BYTE %INTEGER  CONT CHAR 1   , MODE
! CONT CHAR 1 holds the value of the first control character of mode.
! MODE holds the dercoded value of CONT CHAR 1.
!
%OWN %BYTE %INTEGER FAULT COUNT = 0, WARNING COUNT = 0
! These count the number of faults/warnings found in the input.
!
%OWN %INTEGER ELEMENT COUNT = 0
! This counts the number of elements which have been plotted, it is
! used to give the approximate location of faults.
!
%OWN %BYTE %INTEGER PEN DOWN = 2
! This is 0 when drawing tool is up, and 1 when drawing tool is down.
!
!
%CONST %BYTE %INTEGER NEW PAGE THROW = 60
%OWN %BYTE %INTEGER LINE COUNT = 0
! These control the layout of the listing file.
!
!
! The following are symbols with special significance to the program.
%CONST %BYTE %INTEGER  NULL = 0, CR = 13, LF = 10
%CONST %BYTE %INTEGER  EOT = 4   ;  ! This indicates the end of plot.
%CONST %BYTE %INTEGER  DEL = 127 ;  ! This is always ignored.
%CONST %BYTE %INTEGER  ESC = '\' ;  ! This is the escape symbol and
!                                     indicates a change of mode.
!
!
%CONST %INTEGER CONTROL STREAM = 0
%CONST %INTEGER  CODE   STREAM = 1
%CONST %INTEGER  LIST   STREAM = 2
!
!
! The following constants are used in the decoding of the first control
! character after an escape character. These indicate the mode (or sub-
! mode in the case of PLOT mode) which we must enter.
%CONST %BYTE %INTEGER  INVALID = 10,      LINE R = 0,     ARC C R = 1
%CONST %BYTE %INTEGER   LINE A =  2,     ARC C A = 3, COARSE MODE = 4
%CONST %BYTE %INTEGER  ARC A R =  5,   FINE MODE = 6,     ARC A A = 7
%CONST %BYTE %INTEGER   CIRCLE =  8, ASSIST MODE = 9
!
! This array is used to decode the first control character of a new mode.
! It maps all the possible characters onto the MODE/SUB-MODE which they
! represent.
%CONST %BYTE %INTEGER %ARRAY  MODE SELECT (0:126) =
 INVALID,LINER(0),ARCCR,LINEA,ARCCA,INVALID,ARCAR,INVALID,ARCAA,CIRCLE,
 INVALID(7),LINER,ARCCR,LINEA,ARCCA,INVALID,ARCAR,INVALID,ARCAA,CIRCLE,
 INVALID(7),LINER,ARCCR,LINEA,ARCCA,INVALID,ARCAR,INVALID,ARCAA,CIRCLE,
 INVALID(7),LINER,ARCCR,LINEA,ARCCA,INVALID,ARCAR,INVALID,ARCAA,CIRCLE,
 INVALID(7),LINER,ARCCR,LINEA,ARCCA,INVALID,ARCAR,INVALID,ARCAA,CIRCLE,
 INVALID(7), COARSE MODE, INVALID, FINE MODE, ASSIST MODE, INVALID (5),
 INVALID(7),LINER,ARCCR,LINEA,ARCCA,INVALID,ARCAR,INVALID,ARCAA,CIRCLE,
 INVALID(*)
!
!
! The following is the list of fault mnemonics.
!
! WARNINGS:
%CONST %BYTE %INTEGER   TNU = 1     ;! You have stopped with Tool Not Up.
%CONST %BYTE %INTEGER   DPU = 2     ;! You started Using the Default Pen.
%CONST %BYTE %INTEGER   NBS = 3     ;! You have assumed No I Buffer Store
%CONST %BYTE %INTEGER   HSR = 4     ;! Hardware Speed Reduction applied.
%CONST %BYTE %INTEGER   MFU = 5     ;! Magnification Facility Used.
!
! FAULTS:
%CONST %BYTE %INTEGER   CCI = 21    ;! Control Character 1 is Invalid.
%CONST %BYTE %INTEGER   INS = 22    ;! Invalid Numerical Symbol
%CONST %BYTE %INTEGER   ISC = 23    ;! Invalid Second control Caracter.
%CONST %BYTE %INTEGER   IPC = 24    ;! Invalid Plot Character
%CONST %BYTE %INTEGER   KOU = 25    ;! Knife Option Used, no analysis pos.
%CONST %BYTE %INTEGER   IMP = 26    ;! Invalid sym. for Multiple Pen use.
%CONST %BYTE %INTEGER   IOC = 27    ;! Invalid Orientataion Character.
%CONST %BYTE %INTEGER   AOV = 28    ;! Addressing out of Virtual Space.
!
! DISASTERS:
%CONST %BYTE %INTEGER   BEI = 41    ;! Bad Point to End Input.
!
!
!
%CONST %STRING (30) VERSION = "PROOF  :  Version 1.0"
!
!
!
%CONST %BYTE %INTEGER  FULL=0, QRTR=2, SLOW=3 ; ! HALF=1
! These are used as mnenonics for the different plotter speeds.
%CONST %STRING (4) %ARRAY SPEEDMAP(0:3)= "Full"," 1/2"," 1/4","Slow"
!
%OWN %BYTE %INTEGER  MAX SPEED = FULL       ;! This holds the speed
!                                              which is set by P mode.
%CONST %INTEGER MAX RAD AT FS = 256
! This is the max. radius of curve that can be drawn at full speed.
!
!
%OWN %BYTE %INTEGER  PEN SLOT = 100     ;! Holds the current pen slot.
!
%OWN %BYTE %INTEGER  DRAWH FLAG = 1   ;! =1 => Draw header when we plot
!
%OWN %BYTE %INTEGER MAGNIFICATION = 1 ;! (USED WITH LIGHT PENS)
!
%OWN %BYTE %INTEGER C PLOT FLAG = 0 ;! 1=> Consecutive Plots => No BS
!
%OWN %INTEGER C X POS = 0 , C Y POS = 0
! These are used to convert relative moves to absolute ones for STAMP
!
%OWN %BYTE %INTEGER STOPPING = 1    ;! 1=>Must Stop , 0 =>no req. to stop
!
!
!*********************************************************************
!*                                                                   *
!*                                                                   *
!*    NOW  FOLLOWS  THE  ROUTINES  USED  BY  THE  PROGRAM            *
!*                                                                   *
!*                                                                   *
!*********************************************************************
!
!
%ROUTINE NEW PAGE
   ! THIS GIVES A NEW PAGE ON THE CURRRENT OUTPUT STREAM.
   PRINT SYMBOL (12)
   LINE COUNT = 0
%END
!
!
%ROUTINE THROW NL
   !This throws a newline onto the  current output stream.
   NEWLINE
   LINE COUNT = LINE COUNT + 1
%END
!
!
%ROUTINE READ CH (%BYTE %INTEGER %NAME  CHAR)
   ! The symbol DEL is always ignored by the plotter. This routine is 
   ! used in place of READ SYMBOL , and filters out the DEL's.
   READ SYMBOL (CHAR)  %UNTIL  CHAR#DEL
%END
!
!
%ROUTINE %SPEC FAIL (%INTEGER REASON, %STRING(50) MESSAGE)
!
!
%ROUTINE READ SYM (%BYTE %INTEGER %NAME  SYM)
   ! This routine filters out CR,LF, and NULL 's from the input stream
   ! when reading. It warns if they have been used because this means
   ! that the plotter must have no Input Buffer Store. This routine is
   ! used within Plot Mode.
   %CYCLE
      READ CH (SYM)
      %IF SYM = LF %OR SYM = CR %OR SYM = NULL %START
          FAIL (NBS, "No Input Buffer Store to be used")
      %FINISH %ELSE %RETURN
   %REPEAT
%END
!
!
%ROUTINE HEADER
   ! This routine outputs a page header on the listing  file.
   PRINT STRING ("   DETAILS OF ELEMENT     SPEED  SCALE  STOP")
   PRINT STRING ("      X      Y    (X2    Y2)")
   THROW NL
%END
!
!
%ROUTINE PUT MODE (%STRING (30) MODE)
   ! This outputs a message to the listing file giving details of the 
   ! mode which has been entered.
   NEW PAGE %IF LINE COUNT >= NEW PAGE THROW
   C PLOT FLAG = 0
   SELECT OUTPUT (LIST STREAM)
   THROW NL
   PRINT STRING (MODE.":")
   THROW NL
%END
!
!
%ROUTINE HEAD MODE
   ! This ignores all the symbols until the next escape character is
   ! encountered,  ie.  until the plotter is required to enter a new
   ! mode.   The use of this is to allow COMMENTS about the tape for 
   ! your own use,  they are not sent to the code file, but are sent 
   ! to the listing.
   %BYTE %INTEGER SYM
   %INTEGER I

   SELECT OUTPUT (LIST STREAM)
   READ CH (SYM)
   SPACES (3)
   %for I=1,1,71 %cycle
      %EXIT %IF SYM = ESC %OR SYM = EOT
      PRINT SYMBOL (SYM)
      %IF SYM = NL %START
          I = 1
          LINE COUNT = LINE COUNT + 1
          NEW PAGE %AND THROW NL %IF LINE COUNT > NEW PAGE THROW
          SPACES (3)
      %FINISH
      ! We force a new line after there are 70 items on the line.
      %IF I=70 %THEN SYM=NL %ELSE READ CH (SYM)
   %REPEAT
   THROW NL
%END
!
!
%ROUTINE FAIL (%INTEGER REASON, %STRING (50) MESSAGE)
   ! If a fault occurs then this routine is called. The element in the
   ! array fixtures is decremented, and this is used to supress faults
   ! if too many of the same fault occur.
   ! WARNINGS are only allowed to occur once , and these are mapped to
   ! elements one to twenty of the array, FAULTS are reported 10 times
   ! before they are suppressed,    elements 21 to 40 of the array are 
   ! used for supressing too many FAULTS. Any reason over 40 is treated
   ! as a DISASTER.
   !
   !
   %SWITCH SW(0:2)
   %INTEGER TYPE
   %OWN %INTEGER %ARRAY  FAILURES (1:50) = 1(20), 10(*)
   !
   !
   %ROUTINE SEND MESSAGE (%INTEGER STREAM)
      ! This sends the fault message to the appropriate stream, and gives
      ! the approximate point where the decoding failed.
      %CONST %STRING (15) %ARRAY TYPE MAP (0:2) = "?  WARNING  : ",
                            "*  FAULT    : ","** DISASTER : "

      SELECT OUTPUT (STREAM)
      PRINT STRING (TYPE MAP(TYPE).MESSAGE." at/after element")
      WRITE (ELEMENT COUNT,1)
      NEWLINE
   %END
   !
   %ROUTINE CLEAR MODE
      ! This routine reverts to "head mode" until a new mode is reached,
      ! if a true FAULT has occured (ie. not a WARNING)
      ! This ensures that we latch onto a valid possition to restart the
      ! analysis.
      HEAD MODE
   %END
   !
   !
   FAILURES (REASON) = FAILURES (REASON) - 1
   TYPE = REASON // 20
   %IF FAILURES (REASON) < 0 %START
       CLEAR MODE %IF TYPE = 2
       %RETURN
   %FINISH
   SEND MESSAGE (CONTROL STREAM)
   SEND MESSAGE (LIST STREAM)
   THROW NL
   -> SW (TYPE)

SW(0): ! Warnings
       WARNING COUNT = WARNING COUNT + 1
       %RETURN

SW(1): ! Failures
       FAULT COUNT = FAULT COUNT + 1
       CLEAR MODE
       %RETURN %UNLESS FAULT COUNT >10
       MESSAGE = "TOO MANY FAULTS"
       SEND MESSAGE (CONTROL STREAM)
       SEND MESSAGE (LIST STREAM)

SW(2): ! Disaster
       NEWLINES (2)
       %STOP
%END
!
!
%ROUTINE READ NUMBER (%INTEGER %NAME NUM)
   ! This routine reads a number from the input which is made up of
   ! four symbols.
   %INTEGER I
   %BYTE %INTEGER %ARRAY SYMS(0:3)

   NUM = 0
   %for I=0,1,3 %cycle
      READ SYM (SYMS(I))
      %UNLESS '0'<=SYMS(I)<='?' %START
          FAIL (INS,"INVALID NUMERICAL SYMBOL '".TOSTRING(SYMS(I))."'")
          %RETURN
      %FINISH
   %REPEAT
   %for I=3,-1,0 %cycle
      NUM = (NUM<<4)!(SYMS(I)-'0')
   %REPEAT
%END
!
!
%ROUTINE COARSE ORIENTATION MODE
   %CONST %BYTE %INTEGER DISC = 1
   %CONST %BYTE %INTEGER NUMS = 63
   ! NUMS = 63 if DISC 1 is used (prefered)
   ! NUMS = 30 if DISC 0 is used (not prefered)
   !
   ! If the disc (normally set to 1) is required to be DISC 0 then
   ! change the value of DISC to zero (normally one), and set NUMS 
   ! to the appropriate value.
   !
   %CONST %BYTE %INTEGER I PEN = 0
   ! This defines whether we are analysing for an Ink Pen plotter, or
   ! if I PEN is zero then a light pen plot is assumed.
   !
   %BYTE %INTEGER CC2,ORIENT
   %STRING (5) %NAME SHAPE
   %SWITCH SW(0:126)
   %CONST %STRING (20) %ARRAY APERTURES 1 (0:63) =
     "Target Dowel"   ,"Large Pear" ,"Small Pear" ,".062 Land Round",
     "2.5 mm Circle"  ,"Transformation Point"     ,"Flag Point",
     "Visual Centroid",".075-.050 Land"           ,".120-.070 Land",
     ".070-.120 Land" ,".100-.050 Land"           ,".050-.100 Land",
     ".090 Land Round",".080 Land Round"          ,".065 Land Round",
     ".058 Land Round",""(9) ,".002 Track" ,".005 Track" ,".010 Track",
     ".0125 Track" ,".015 Track" ,".030 Land Round" ,".050 Land Round",
     ".060 Land Round",".075 Land Round",".100 Land Round",
     ".125 Land Round",".150 Land Round",".175 Land round",
     ".050 Land Square",".060 Land Square",".075 Land Square",
     ".100 Land Square",".020 Track",".025 Track",".030 Track",
     ".040 Track",".050 Track",".055 Track",".070 Track",
     ".120 Track",""(7),".060 Track",".075 Track",".100 Track",
     ".125 Track",".150 Track",".175 Track"

   %OWN %STRING (5) %ARRAY TYPE SIZE 1 (0:63) =
     "N 0","P 1","P 2","R 62","C 0","X 0","F 0","V 0","O  75","O 120",
     "O  70","O 100","O  50","R  90","R  80","R  65","R  58",""(9),
     "T   2","T   5","T  10","T  12","T  15","R  30","R  50","R  60",
     "R  75","R 100","R 125","R 150","R 175","S  50","S  60",
     "S  75","S 100","T  20","T  25","T  30","T  40","T  50","T  55",
     "T  70","T 120",""(7),"T  60","T  75","T 100","T 125","T 150",
     "T 175"

   %CONST %STRING (20) %ARRAY APERTURES 0 (0:30) =
     ".0125 Track",".010 Track",".015 Track",".020 Track",".025 Track",
     ".030 Track",".040 Track",".050 Track",".075 Track",".100 Track",
     ".125 Track",".150 Track",".175 Track",".050 Land Round",
     ".060 Land Square",".075 Land Round",".100 Land Round",
     ".125 Land Round",".150 Land Round",".175 Land Round",
     ".187 Target Dowel",".050 Land Square",".075 Land Square",
     ".100 Land Square",".005 Track",".0125 Track","",
     ".080 Lnad Round",""(3)

   %OWN %STRING (5) %ARRAY TYPE SIZE 0 (0:30) =
     "T  12","T  10","T  15","T  20","T  25","T  30","T  40","T  50",
     "T  75","T 100","T 125","T 150","T 175","R  50","S  60","R  75",
     "R 100","R 125","R 150","R 175","N   0","S  50","S  75","S 100",
     "T   5","T  12","","R  80",""(3)

   C PLOT FLAG = 0
   READ CH (CC2)
   %IF CC2&2_1000#0 %THEN %C
       FAIL (ISC,"Invalid Second Control Character '".TOSTRING(CC2)."'")
   FAIL (KOU,"Knife Option use Not Valid") %IF CC2&2_1000#0
   %IF MAX SPEED > CC2&3 %START
      MAX SPEED = CC2  & 3
      PRINT STRING ("   Speed Changed to ")
      PRINT STRING (SPEED MAP (MAX SPEED))
      THROW NL
   %FINISH
   %IF CC2 <= 43 %START
      FAIL (MFU, "Magnification Facility Used")
      ! SET MAGNIFICATION ?????????
   %FINISH
   %IF MAGNIFICATION # 1 %AND 100 <= CC2 <=103 %START
      MAGNIFICATION =1
      PRINT STRING ("   Magnification reset to one")
      THROW NL
   %FINISH
   !
   !
   !
   %IF I PEN # 0 %START
   !
   ! If pen plotting ,  we now decide on the pen to be selected.
   ! (Assuming an EP177 Turret).
   !
   FAIL (IMP, "Invalid Character for Multiple Pen Use") %IF CC2 # '@'
   READ CH (ORIENT)
   -> SW (ORIENT)

SW('@'): PRINTSTRING ("   Pen one") %AND PEN SLOT = 1 %IF PEN SLOT # 1
         -> CONT

SW('H'): PRINTSTRING ("   Pen two") %AND PEN SLOT = 2 %IF PEN SLOT # 2
         -> CONT

SW('P'): PRINTSTRING ("   Pen three") %AND PENSLOT = 3 %IF PENSLOT # 3
         -> CONT

SW('X'): PRINTSTRING ("   Pen four") %AND PEN SLOT = 4 %IF PENSLOT # 4
         -> CONT

SW(' '): PRINTSTRING ("   Pen five") %AND PEN SLOT = 5 %IF PENSLOT # 5
         -> CONT

SW('('): PRINTSTRING ("   Pen six") %AND PEN SLOT = 6 %IF PEN SLOT # 6
         -> CONT

SW('0'): PRINTSTRING ("   Pen seven") %AND PENSLOT = 7 %IF PENSLOT # 7
         -> CONT

SW('8'): PRINTSTRING ("   Pen Eight") %AND PENSLOT = 8 %IF PENSLOT # 8
         -> CONT

   CONT: PRINT STRING ("Choosen")
         THROW NL
         SKIP SYMBOL
         %RETURN
   %FINISH
   !
   ! If we are using a light pen then the apparture is selected.
   READ CH (ORIENT)
   %IF ORIENT >=64 %THEN ORIENT = ORIENT - 64
   FAIL (IOC, "Invalid Orientation Caracter") %AND %RETURN %IF ORIENT >NUMS
   %IF PEN SLOT # ORIENT %START
       PEN SLOT = ORIENT
       PRINT STRING ("   Projector Symbol Selected  :  ")
       %IF DISC = 1 %THEN PRINT STRING (APERTURES 1 (ORIENT))      %c
                    %ELSE PRINT STRING (APERTURES 0 (ORIENT))
       THROW NL
       SKIP SYMBOL
       SELECT OUTPUT (CODE STREAM)
       %IF DISC = 1 %THEN SHAPE == TYPE SIZE 1 (ORIENT)        %C
                    %ELSE SHAPE == TYPE SIZE 0 (ORIENT)
       PRINT STRING ("P".SHAPE)
       NEWLINE
   %FINISH
%END
!
!
%ROUTINE FINE ORIENTATION MODE
   ! This routine deals with changes to the plotter head orientation wrt.
   ! the base line.
   %BYTE %INTEGER CC2
   %INTEGER X,Y
   %ROUTINE PRINT (%INTEGER QUO,DIV,PLACES)

      QUO = QUO-DIV %WHILE QUO>=DIV
      WRITE (QUO,1)
      PRINT SYMBOL ('.')
      %CYCLE
         %EXIT %IF PLACES <= 0
         PLACES = PLACES -1
         QUO = QUO * 10
         QUO = QUO-DIV %WHILE QUO>DIV
         PRINT SYMBOL (QUO+'0')
      %REPEAT
   %END

   C PLOT FLAG = 0
   X=0
   C X POS = 0
   C Y POS = 0
   READ CH (CC2)
   %IF CC2='N' %OR CC2='I' %START
      %IF CC2='N' %THEN PRINT STRING ("   Normal ")           %C
                  %ELSE PRINT STRING ("   Inverted ")
      PRINT STRING ("Orientation of Plotting Head Choosen")
      THROW NL
      SKIP SYMBOL
      %IF CC2='N' %THEN Y=0 %ELSE Y=1
      X = 1
   %FINISH
   %IF CC2='E' %START
      READ NUMBER (X)
      READ NUMBER (Y)
      PRINT STRING ("Base Line Angle Set to  arctan")
      PRINT (X,Y,4)
      THROW NL
      SKIP SYMBOL
   %FINISH
   %IF X = 0 %START
       FAIL (ISC,"Invalid Second Control Character '".TO STRING (CC2)."'") 
       %RETURN
   %FINISH
   SELECT OUTPUT (CODE STREAM)
   PRINT SYMBOL ('F')
   WRITE (X,1)
   WRITE (Y,1)
   NEWLINE
%END
!
!
%ROUTINE PLOT MODE
   ! This routine deals with the plotting instructions.
   %CONST %STRING (25) %ARRAY PTYPE(0:8) =
          "Line Rel","CW Arc Rel","Line Abs","CW Arc Abs","",
          "ACW Arc Rel","","ACW Arc Abs","Circle"
   ! This array gives the possible types of lines that can be drawn.
   !
   %CONST %BYTE %INTEGER %ARRAY  STCODE (0:8) =
          'L','I','L','I','E','D','E','D','C'
   ! This array gives the code symbols for the different shapes.
   !
   %CONST %INTEGER %ARRAY  NUM PAR (0:8) = 2,4,2,4,0,4,0,4,2
   ! This gives the number of parameters expected for each type of plot
   !
   %CONST %BYTE %INTEGER CONTINUOUS = 1, INVISIBLE = 2, DOTTED = 3
   %CONST %BYTE %INTEGER     DASHED = 4,     CHAIN = 5,  FLASH = 6
   ! These are the codes for the different modes of symbol drawing.
   %CONST %STRING (15) %ARRAY  LTYPEN(1:6) = "   Continuous ",
    "   Invisible ","   Dotted ","   Dashed ","   Chain ","   Flash "
   !
   %CONST %BYTE %INTEGER %ARRAY LTCODE (1:6) = 'N','I','.','-','C','F'
   ! This gives the code for the different line types
   !
   !
   ! The following array decodes the second control character.
   %CONST %BYTE %INTEGER %ARRAY  CC2 DECODE (0:126) =
          INVALID ,  INVALID, CONTINUOUS, INVALID(13),
          INVISIBLE, INVALID, CONTINUOUS, INVALID(13),
          INVISIBLE, INVALID, CONTINUOUS, INVALID (3),   DOTTED,
          INVALID(3), DASHED, INVALID(3), CHAIN,        INVALID,
          INVISIBLE, INVALID, CONTINUOUS, INVALID (3),   DOTTED,
          INVALID(3), DASHED, INVALID(2), FLASH, CHAIN, INVALID,
          INVISIBLE, INVALID, CONTINUOUS, INVALID(10),    FLASH,
          INVALID(4),     CONTINUOUS,  INVALID(15),  CONTINUOUS,
          INVALID(3), DOTTED, INVALID(3), DASHED,    INVALID(3),
          CHAIN,  INVALID(3), CONTINUOUS, INVALID (3),   DOTTED,
          INVALID(3), DASHED, INVALID(3), CHAIN
   !
   !
   %CONST %BYTE %INTEGER %ARRAY PEN DETAILS (1:6) = 1,0,1,1,1,0
   ! This allows us to know the possition of the pen after plots.
   !
   !
   %BYTE %INTEGER  CC2   ;! This is the second control character
   %BYTE %INTEGER SPEED,STOP           ;! These hold mode INFO.
   %INTEGER %ARRAY PARMS(1:4)          ;! These hold the numerical parms.
   %INTEGER LTYPE, I, RAD              ;! Line TYPE
   %STRING (5) SCALE
   %STRING (30) LINE  
   !
   %ROUTINE CHECK RADIUS
      ! This routine checks the radius of curvature of the element.
      %INTEGER DY,DX
      %SWITCH RC(0:8)

      RAD = 10000 %AND %RETURN %IF SPEED = QRTR %OR SPEED = SLOW
      ! There is no need to check the radius.
      -> RC (MODE)
      
RC(LINEA): RC(LINER): ! We give the radius a dummy value for lines
           RAD = 10000
           %RETURN
 
RC(CIRCLE):! We find the radius of the circle
           DX = | PARMS(1) |
           DY = | PARMS(2) |
           -> CHECK

RC(ARCAA): RC(ARCCA):
           DX = | PARMS(1) - PARMS(3) |
           DY = | PARMS(2) - PARMS(4) |
           -> CHECK

RC(ARCCR): RC(ARCAR):
           DX = | PARMS(3) |
           DY = | PARMS(4) |

CHECK:   ! We now find the approximate radius.
         ! The method is done by cases and is very rough  O(10%).
         ! The value found is such that the error may be found in
         ! cases where the restriction would just not apply.
         ! If the warning is given then the user can check themselves
         ! to see if it was justified.
   
         %IF  DX > DY  %START   ;! We swap them over to reduce case analysis
              RAD = DX
              DX  = DY
              DY  = RAD
         %FINISH
         
         RAD=10000 %AND %RETURN %IF DY > MAXRADATFS

         %IF DX=0 %START
             SPEED = QRTR %IF DY < MAX RAD AT FS
             %RETURN
         %FINISH
 
         %IF  DX < DY//2  %START
              RAD = DY + (DY>>3)    ;!  RAD ^ 9 DY / 8
              SPEED = QRTR %IF RAD < MAX RAD AT FS
              %RETURN
         %FINISH
  
         %IF  DX < 3*DY//2 %START
              RAD = DY + (DY>>4)*3  ;!  RAD ^ 19 DY / 16
              SPEED = QRTR %IF RAD < MAX RAD AT FS
              %RETURN
         %FINISH

         RAD = DY + (DY>>3)*5   ;!   RAD ^ 11 DY / 8
         SPEED = QRTR %IF RAD < MAX RAD AT FS
   %END
 
   %ROUTINE SET POS AND GIVE PARM
      ! This routine updates the current possition (as all moves
      ! passed to STAMP are absolute.) It also outputs the parameters.
      %CONST %INTEGER TRUE = 1, FALSE = 0
      !
      %CONST %BYTE %INTEGER %ARRAY ABSOLUTE(0:8) =
         FALSE(2), TRUE(2), FALSE(3), TRUE, FALSE
      !
      %INTEGER RAD,O X POS, O Y POS
      !
      %IF ABSOLUTE(MODE)=TRUE %START
          C X POS = PARMS(1)
          C Y POS = PARMS(2)
          WRITE (C X POS,1)
          WRITE (C Y POS, 1)
          %RETURN %IF MODE = LINEA
          WRITE (PARMS(3),1)
          WRITE (PARMS(4),1)
          %RETURN
      %FINISH
      ! We have to deal with relative moves now.
      O X POS = C X POS
      O Y POS = C Y POS
      C X POS = O X POS + PARMS(1)
      C Y POS = C Y POS + PARMS(2)
      WRITE (C X POS,1)
      WRITE (C Y POS,1)
      %RETURN %IF MODE = CIRCLE %OR MODE = LINER
      WRITE (O X POS - PARMS(3) ,1)
      WRITE (O Y POS - PARMS(4) ,1)
   %END


   HEADER %IF DRAW H FLAG = 1
   FAIL (NBS,"No Input Buffer Store should be used (\)") %IF CPLOTFLAG=1
   %CYCLE
      ELEMENT COUNT = ELEMENT COUNT + 1
      ! This gives the type of plot required.
      READ SYM (CC2)
      LTYPE = CC2 DECODE (CC2)
      %UNLESS LTYPE <7 %START
          FAIL (ISC,"INVALID SECOND CONT. CHAR. '".TOSTRING(CC2)."'")
          %RETURN
      %FINISH
      PEN DOWN = PEN DETAILS (LTYPE) ;! We record the position of the pen
      LINE = LTYPEN(LTYPE). PTYPE(MODE)
      %for I = 1,1,NUM PAR (MODE) %cycle
         READ NUMBER (PARMS(I))
      %REPEAT
      ! This has read in all the details of the current element.
      !
      SELECT OUTPUT (LIST STREAM)
      PRINT STRING (LINE)
      SPACES (27 - LENGTH (LINE))
      !
      !
      ! We now find the speed of the plot.
      !
      !
      SPEED = CC2>>4 & 3
      SPEED = MAX SPEED %IF MAX SPEED > SPEED
      ! Speed is always the lowest of the alternatives.
      SPEED = FULL %IF LTYPE = INVISIBLE
      ! Hardware draws invisible lines at full speed
      CHECK RADIUS
      PRINT STRING (SPEED MAP (SPEED))
      SPACES (3)
      !
      !
      STOPPING = 1 %IF CONTCHAR1>>6 & 1 = 1 ;! Cancel ability for no stop mode
      STOPPING = 0 %IF CC2>>6 & 1 = 1 ;! allow no stop mode again
      !
      !
      %IF CONTCHAR1 & 8_40 = 1 %THEN SCALE = "1/16" %ELSE SCALE = "Norm"
      PRINT STRING (SCALE)
      !
      !
      STOP = 1
      STOP = 0 %IF CONT CHAR 1 & 8_20 = 1 %AND STOPPING = 0
      %IF STOP=1 %THEN PRINTSTRING ("   Yes") %ELSE PRINTSTRING ("    No")
      !
      !
      ! We output the numbers to the listing file.
      !
      %for I = 1,1,NUM PAR (MODE) %cycle
         WRITE (PARMS(I),6)
      %REPEAT
      THROW NL
      FAIL (DPU, "Default Pen Used") %IF PEN SLOT=100 %AND LTYPE#INVISIBLE
      FAIL (HSR, "Hardware Speed Reduction(s) Applied") %IF RAD<=MAXRADATFS
      !
      ! Now we send code to the object stream.
      !
      SELECT OUTPUT (CODE STREAM)
      PRINT SYMBOL (STCODE(MODE))
      PRINT SYMBOL (LTCODE(LTYPE))
      SET POS AND GIVE PARM
      NEWLINE
      !
      !
      ! We now test if any more plotting iunstructions follow:
      !
      READ SYM (CONT CHAR 1)
      C PLOT FLAG = 1 %AND %RETURN %IF CONT CHAR 1 = ESC
      MODE = MODE SELECT (CONT CHAR 1)
      %IF MODE>8 %OR MODE = FINE MODE %OR MODE = COARSE MODE %START
          FAIL (IPC,"INVALID PLOT CHARACTER '".TOSTRING(CONTCHAR1)."'")
          %RETURN
      %FINISH
      %IF LINE COUNT > NEW PAGE THROW %START
          NEW PAGE
          PUT MODE ("PLOT MODE")
          HEADER
      %FINISH
   %REPEAT
%END
!
!
%ROUTINE DECODE MODE (%INTEGER MODE)
   ! This selects the mode that we now require.
   %SWITCH SW(0:9)

   -> SW (MODE)

SW(*): PUT MODE ("PLOT MODE")
       PLOT MODE
       %RETURN

SW(COARSE MODE): PUT MODE ("COARSE ORIENTATION MODE")
                 COARSE ORIENTATION MODE
                 DRAW H FLAG = 1
                 %RETURN

SW(FINE MODE): PUT MODE ("FINE ORIENTATION MODE")
               FINE ORIENTATION MODE
               DRAW H FLAG = 1
               %RETURN

SW(ASSIST MODE): SELECT OUTPUT (CODE STREAM)
                 PRINT STRING ("A")
                 NEWLINE
                 PUT MODE ("ASSIST MODE")
                 FAIL (TNU,"Plotting Tool not up") %IF PEN DOWN # 0
                 HEAD MODE
                 DRAW H FLAG = 1
%END
!
!
%ROUTINE GIVE STATISTICS  (%INTEGER STREAM)
   SELECT OUTPUT (STREAM)
   NEWLINE
   PRINT STRING (" Input ")
   %IF WARNING COUNT = 0 %AND FAULT COUNT = 0 %START
       PRINT STRING ("Accepted for Plotter")
   %FINISH %ELSE %START
       PRINT STRING ("Contained")
       %IF FAULT COUNT = 0 %THEN PRINT STRING (" no")        %C
                           %ELSE WRITE (FAULT COUNT,1)
       PRINT STRING (" fault")
       PRINT SYMBOL ('s') %IF FAULT COUNT # 1
       PRINT STRING (" and")
       %IF WARNING COUNT = 0 %THEN PRINT STRING (" no")      %C
                             %ELSE WRITE (WARNING COUNT,1)
       PRINT STRING (" warning")
       PRINT SYMBOL ('s') %IF WARNING COUNT # 1
   %FINISH
   NEW LINE
   WRITE (ELEMENT COUNT,1)
   PRINT STRING (" elements plotted")
   NEW LINES (2)
%END
!
!
%ROUTINE INITIALISE
   ! This routine sets up the initial streams when the programme starts
   SELECT INPUT (1)
   SELECT OUTPUT (LIST STREAM)
   NEWLINE
   SPACES (25)
   PRINT STRING (VERSION)
   NEWLINE
   PUT MODE ("HEAD MODE")
   HEAD MODE              ;! Skip the initial header.
   LINE COUNT = 2
%END
!
!
!**************************************************************
!*                                                            *
!*                                                            *
!*                     MAIN  PROGRAMME BODY                   *
!*                                                            *
!*                                                            *
!**************************************************************
   !
   %ON %EVENT 1,9 %START
       %IF EVENT_EVENT = 9 %START
           %UNLESS CONTCHAR1#ASSIST MODE %AND CONTCHAR1#EOT %THEN %C
               FAIL (BEI, "Bad point to end")
           PUT MODE ("END PLOT MODE")
           GIVE STATISTICS (CONTROL STREAM)
           NEWLINES(2)
           GIVE STATISTICS (LIST STREAM)
           NEWPAGE
           SELECT OUTPUT (CODE STREAM)
           PRINT STRING ("E")
           NEWLINE
           %STOP
       %FINISH
       FAIL (AOV,"Addressing out of Virtual Space")
       C X POS = 0
       C Y POS = 0
   %FINISH
   !
   INITIALISE %IF ELEMENT COUNT = 0
   !
   %CYCLE
      READ CH (CONT CHAR 1)
      %SIGNAL %EVENT 9 %IF CONT CHAR 1 = EOT      ;! END OF INPUT TAPE
      MODE = MODE SELECT (CONT CHAR 1)
      %IF MODE < 10 %THEN  DECODE MODE (MODE)            %C
          %ELSE FAIL(CCI,"Control Character Invalid '".TOSTRING(CONTCHAR1)."'")
   %REPEAT
   !
   !
   !*************************************************************
   !*                                                           *
   !*                                                           *
   !*        END  OF  INPUT  RECOGNITION  PHASE                 *
   !*                                                           *
   !*                                                           *
   !*************************************************************
   !
%END %OF %PROGRAM
