! EDWIN driver for the HP plotter range.

%external %string (15) %fn %spec DATE
%external %string (15) %fn %spec TIME
%external %routine %spec PROMPT (%string (63) S)
%external %routine %spec TTMODE (%integer MODE)
%external %routine %spec TTPUT (%integer CH)
%external %integer %fn %spec TTREAD
%external %routine %spec FLUSH OUTPUT
%external %routine %spec CLOSE OUTPUT
%external %routine %spec OPEN OUTPUT (%integer st, %string (255) file)
%external %integer %fn %spec INSTREAM
%external %integer %fn %spec OUT STREAM
%external %string (63) %fn %spec ITOS (%integer I, P)
%external %string (63) %fn %spec RTOS (%long %real R, %integer N, P)
%external %string (127) %fn %spec OUT FILE NAME
%external %string (255) %fn %spec UINFS (%integer I)
%external %integer %spec DEVICE, VIEWING
!%external %long %real %fn %spec SIN (%long %real A)
!%external %long %real %fn %spec COS (%long %real A)
!%external %long %real %fn %spec TAN (%long %real A)
%const %real D TO R = 57.2958; ! Magic number converts degrees to rads.

! Control characters
%const %integer TRUE = 0,   FALSE = 1
%const %integer ETX = 3
%const %integer ESC =27
%const %integer DEL = 127
%const %integer BUFF SIZE = 251

! Screen information
%own %integer PLOT ACTIVE = FALSE;  ! FALSE => using terminal, TRUE => PLOTTER active
%own %integer LAST COM = 0;   ! Used to optimise lines in the HP protocol
%own %integer SX = 0;         ! Current device position
%own %integer SY = 0
%own %integer XL = 0, YB = 0; ! Lower window bounds.
%own %integer YT = 25 * 400;  ! Upper device window bound.
%own %integer XR = 40 * 400;  ! Right hand side of device window
%own %byte CUR COL = 1;       ! Current colour.
%own %byte PM = FALSE;        ! Pending move.
%own %byte PC = FALSE;        ! Pending colour change.
%own %byte LOW QUAL = TRUE;   ! Character Quality, FALSE => proportional spaced sets
%own %byte NEWFRAMED = FALSE; ! TRUE => NEW FRAME done
%own %byte TEXT MODE = FALSE; ! TRUE while in text mode
%own %integer INBUFF = 32;    ! This is the initialisation code

! Configuration parameters -

%const %integer LINE = 5;            ! device driver code for LINE ABS
%const %integer MAX ATTRIBUTE = 8
%const %integer MAX COLOUR = 16
%const %integer MAX LINE = 6
%const %integer NUM HP = 2
%const %integer HP7221 = 0, HP7220 = 1, HP7580=2
%own %integer current dev = HP7221
%const %half %array   DEV NUMS (0:NUM HP) =  7221,  7220,  7580
%const %byte %array    NUM PENS (0:NUM HP) =     4,     8,     8
%const %byte %array INTERACTIVE (0:NUM HP) =  TRUE, FALSE,  TRUE
%own %integer %array     X BASE (0:NUM HP) =     0,     0,-15800
%own %integer %array     Y BASE (0:NUM HP) =     0,   700,-11400
! NB: YBASE should be 700 if plotter has auto paper feed (plots above the holes!)
%const %integer %array    MAX X (0:NUM HP) = 16000, 16000, 16000
%const %integer %array    MAX Y (0:NUM HP) = 11400, 10700, 11400
! The following 3 lines are VAX only, if the plotter is an independant device
%const %string (6) %array TERMS (0:NUM HP) =    "",    "", "" { "" => not special device }
!%external %routine %spec SET IN (%string (15) DEV)
!%external %routine %spec SET OUT (%string (15) DEV)
%own %string (15) %array COLOUR NAME (1:MAX COLOUR) =
   "black", "blue", "green", "red", "purple", "orange", "lime green", "brown",
   "turqoise", "gold", "pen 11", "pen 12", "pen 13", "pen 14", "pen 15", "pen 16"
%own %byte %array          SLOT USED (0:MAX COLOUR) = 0, 4, 3, 2, 1, 0 (*)
%own %byte %array        SLOT TO USE (0:MAX COLOUR) = 0, 4, 3, 2, 1, 3, 1, 2, 4, 3, 4, 1 (*)
%const %byte %array  DEF SLOT TO USE (0:MAX COLOUR) = 0, 4, 3, 2, 1, 3, 1, 2, 4, 3, 4, 1 (*)
%const %byte %array  LINE STYLE MAP  (0:MAX LINE)   = '0', '1', '5', '2', '3', '4', '6'
%const %real %array  LINE STYLE LEN  (0:MAX LINE)   = 0.0, 0.5, 2.5, 1.0, 1.5, 2.0, 2.0

%own %string (127) HP NEW FRAME MESSAGE STR = "Enter a new sheet of paper, type YES to continue: "
%own %byte HP NEW FRAME MODE = 'Y'

%external %routine HP SET PEN (%string (15) NAME, %integer LOG NO, SLOT NO)
   %return %unless 1<=LOGNO<=MAX COLOUR
   COLOUR NAME (LOG NO) = NAME
   SLOT TO USE (LOG NO) = SLOT NO
%end

%external %routine HP NEW FRAME MESSAGE (%string (127) MESSAGE, %integer MODE)
   HP NEW FRAME MESSAGE STR = MESSAGE
   HP NEW FRAME MODE = MODE & 95
%end

! Routines for the model 7221 protocol

%routine SBN (%integer N)
   ! This sends a single byte number to the plotter
   N = N+64 %if N&32 = 0
   TTPUT (N)
%end

%routine MBN (%integer N)
   ! A three byte number is sent to the plotter
   %integer NN


   TTPUT (96+N//4096)
   
   NN = (N//64)&63
   NN = NN + 64 %unless NN>31
   TTPUT (NN)

   NN = N&63
   NN = NN + 64 %unless NN>31
   TTPUT (NN)
%end

%routine MBP (%integer X, Y)
   ! Multiple byte pair of numbers (5 bytes)
   %integer N


   TTPUT (96+X//1024)
   
   N = (X//16)&63
   N = N + 64 %unless N>31
   TTPUT (N)

   N = (X&15)*4 + (Y//4096)
   N = N + 64 %unless N>31
   TTPUT (N)
   
   N = (Y//64)&63
   N = N + 64 %unless N>31
   TTPUT (N)

   N = Y&63
   N = N + 64 %unless N>31
   TTPUT (N)
%end

%routine MBA (%integer A)
   ! Gives a multi byte angle
   MBN (INT(2\15*(A/180)))
%end

! Routines for the non-7221 plotters

%routine ADD (%integer ONE, TWO)
   TTPUT (';')
   TTPUT (ONE)
   TTPUT (TWO)
%end

%routine ADD STR (%string (255) STR)
   %integer I
   TTPUT (CHARNO(STR,I)) %for I = 1, 1, LENGTH(STR)
%end

%routine HP OUT NUM (%integer I)
   ADD STR (ITOS (I, 0))
%end

%routine HP OUT REAL (%real R)
   ADD STR (RTOS (R, 0, 2))
%end

%routine HP LINE (%integer X, Y);     ! Go the the current X Y point
   %if LAST COM = LINE %then TTPUT (',') %else %start
       ADD ('P', 'D')
       %return %if SX=X %and SY=Y; ! Just a point
       ADD ('P', 'R')
   %finish
   HP OUT NUM (X - SX)
   TTPUT (',')
   HP OUT NUM (Y - SY)
   LAST COM = LINE
%end

! Protocol Handling routines

%routine HP INSTRUCTION (%integer WHICH)
   TTPUT (ESC);   TTPUT ('.');   TTPUT (WHICH)
%end

%routine RESERVE (%integer N)
   ! Test to see if N chars. will fit in the buffer
   %integer S
   %return %if INTERACTIVE(CURRENT DEV)#TRUE %or CURRENT DEV=HP7580
   IN BUFF = IN BUFF + N
   %if IN BUFF>250 %start
       HP INSTRUCTION ('L')
       FLUSH OUTPUT
       S = IN STREAM
       SELECT INPUT (0)
       PROMPT (TO STRING (DEL))
       N = TTREAD %until N > ' '
       N = TTREAD %until N < ' '; ! Ignore the response
       SELECT INPUT (S)
       IN BUFF = 0
       PROMPT ("Data: ")
   %finish
%end

%routine PON 
   %return %if INTERACTIVE(CURRENT DEV)#TRUE
   TTPUT (ESC) %and TTPUT ('*') %if CURRENT DEV = HP7580 %and TERMS(HP7580)=""
   ! The above line assumes that the plotter will be connected through an
   ! Esprit terminal if it can't be connected directly.  (see also POF)
   HP INSTRUCTION ('(')
   PLOT ACTIVE = TRUE
%end

%routine POF
   RESERVE (BUFF SIZE); ! force out anything which is present.
   TTPUT (';') %if CURRENT DEV # HP7221
   HP INSTRUCTION (')')
   TTPUT (13)
   TTPUT (ESC) %and TTPUT ('?') %if CURRENT DEV = HP7580 %and TERMS(HP7580)=""
   FLUSH OUTPUT
   PLOT ACTIVE = FALSE
%end

%routine END TEXT MODE
   TTPUT (ETX)
   TEXT MODE = FALSE
%end

%routine CHECK PLOTTING AND NO TEXT
   PON %if PLOT ACTIVE # TRUE
   END TEXT MODE %if TEXT MODE = TRUE
%end

%routine SET GRAPHICS LIMITS (%integer LX, LY, HX, HY)
   XL = LX;   XR = HX;   YB = LY;   YT = HY
   RESERVE (25)
   CHECK PLOTTING and NO TEXT
   %if CURRENT DEV = HP7221 %start
       TTPUT ('~');   TTPUT ('W');   MBP (XL, YB);   MBP (XR, YT)
       TTPUT ('~');   TTPUT ('S');   MBP (XR-XL, YT-YB); TTPUT ('}')
   %finish %else %start
       ADD ('I', 'P')
       %if CURRENT DEV = HP7220 %start
           HP OUT NUM (XL);   TTPUT (',');   HP OUT NUM (YB);    TTPUT (',')
           HP OUT NUM (XR);   TTPUT (',');   HP OUT NUM (YT)
       %finish
       ADD ('S', 'C');    TTPUT ('0');   TTPUT (',');   HP OUT NUM (XR-XL)
       TTPUT (',');       TTPUT ('0');   TTPUT (',');   HP OUT NUM (YT-YB)
   %finish
   XL = XL - XBASE(CURRENT DEV)
   YB = YB - YBASE(CURRENT DEV)
%end

%routine FULL GRAPHICS LIMITS
   SET GRAPHICS LIMITS (XBASE(CURRENT DEV), YBASE(CURRENT DEV), MAX X(CURRENT DEV), MAX Y(CURRENT DEV))
%end

%routine CHECK FOR PENDING COLOURS AND MOVES
   %integer IS, REP

   %routine COLOUR (%integer I)
      I = I - NUM PENS (CURRENT DEV) %while I > NUM PENS (CURRENT DEV)
      %if CURRENT DEV = HP 7221 %start
          TTPUT ('v');   SBN (I)
      %finish %else %start
          ADD ('S', 'P');   TTPUT (I + '0')
      %finish
   %end

   CHECK PLOTTING and NO TEXT
   %if PC = TRUE %start
       %if INTERACTIVE(CURRENT DEV)=TRUE %and CUR COL > 0 %and SLOT USED(CUR COL)=0 %start
           ! Ask the user to change to a new pen
           COLOUR (0)
           POF
           IS = IN STREAM
           SELECT INPUT (0)
           PROMPT ("Enter new ".COLOUR NAME(CUR COL)." pen in slot ".ITOS(SLOT TO USE (CUR COL),0).", YES to continue: ")
           READ SYMBOL (REP) %until REP&95='Y'
           READ SYMBOL (REP) %until REP=NL
           SELECT INPUT (IS)
           %for REP = 1, 1, 8 %cycle
                SLOT USED (REP) = 0 %if SLOT USED (REP) = SLOT TO USE (CUR COL)
           %repeat
           SLOT USED (CUR COL) = SLOT TO USE (CUR COL)
           PON
       %finish
       COLOUR (SLOT USED (CUR COL))
   %finish
   %if PM = TRUE %start
       %if CURRENT DEV = HP7221 %start
           TTPUT ('p');   MBP (SX, SY)
       %finish %else %start
           ADD ('P', 'U')
           ADD ('P', 'A');   HP OUT NUM (SX+XL{+xbase(current dev)//2})
           TTPUT (',');   HP OUT NUM (SY+YB{+ybase(current dev)//2})
       %finish
       COLOUR (SLOT USED (CUR COL)); ! To force out move
   %finish
   PC = FALSE
   PM = FALSE
%end

%routine UPDATE
   END TEXT MODE %if TEXT MODE = TRUE
   %if PLOT ACTIVE=TRUE %start
       RESERVE (10)
       PC = TRUE
       PM = TRUE
       CHECK FOR PENDING COLOURS AND MOVES
       POF
   %finish
%end

%routine NEW FRAME
   %integer ST, OLD COL, SYM
   %string (255) OLD PROMPT

   CHECK PLOTTING AND NO TEXT
   SX = XR;   SY = YT;   PM = TRUE;! Goto the edge.
   OLD COL = CUR COL;               ! remember current colour.
   PC = TRUE;  CUR COL = 0;         ! Drop pen
   %if NEW FRAMED = TRUE %start
       %if CURRENT DEV = HP7580 %start
           ADD ('N', 'R');   FLUSH OUTPUT
           ST = OUT STREAM
           SELECT OUTPUT (0)
           PRINT STRING ("Press REMOTE on the plotter to continue");   NEWLINE
           SELECT OUTPUT (ST)
       %finish %else %start
           UPDATE
           %if INTERACTIVE(CURRENT DEV) = TRUE %start
               OLD PROMPT = UINFS (4)
               ST = IN STREAM
               SELECT INPUT (0)
               PROMPT (HP NEW FRAME MESSAGE STR)
               READ SYMBOL (SYM) %until SYM&95=HP NEW FRAME MODE
               %if HP NEW FRAME MODE # NL %start
                   READ SYMBOL (SYM) %until SYM=NL
               %finish
               SELECT INPUT (ST)
               PROMPT (OLD PROMPT)
           %finish
       %finish
   %finish
   NEW FRAMED = TRUE
   ! Restore default state after newframe.
   CUR COL = OLD COL;   SX = XL;   SY = YB;   PM = TRUE;   PC = TRUE
%end
   
%external %routine HPPLOT (%integer COM, X, Y)
   %switch SW (0:9)

   %routine NEW 7221 ATTRIBUTE (%integer X, Y)
      %switch SW(0:MAX ATTRIBUTE)
      %const %integer DASH = 32
   
      -> SW(X)
      
   SW(0): Y=1 %unless 0<=Y<=MAX COLOUR
          PC = TRUE
          CUR COL = Y
          %return
   
   SW(1): TTPUT('~');  TTPUT ('Q')
          %if Y=1 %start
              SBN(DASH + 2); SBN(4); MBN(60)
          %finish
          %if Y=2 %start
              SBN(DASH + 14);  SBN(4);  SBN(DASH + 2); SBN(4); MBN(240)
          %finish
          %if Y=3 %start
              SBN(DASH + 8);  SBN(4);  MBN(120)
          %finish
          %if Y=4 %start
              SBN(DASH + 16);  SBN(4);  MBN(200)
          %finish
          %return
   
   SW(2): TTPUT('~');  TTPUT('%');  Y=Y*100//98;   MBP(Y, Y+Y)
          ! Note that the 100//98 scales the H/W chars to same scale as S/W ones.
          %return
   
   SW(3): TTPUT ('w');   TTPUT ('w');   MBA (Y);   ! Char rot
          %return
   
   SW(4): %return;   ! Ignore attempts to change quality
   
   SW(5): TTPUT ('~');   TTPUT ('P');   MBP (Y,Y); ! Char font
          %return
   
   SW(6): TTPUT ('~');   TTPUT ('/');   MBA (Y);   ! Char slant
          %return
   
   SW(7): ! Ignore any attempts to change intensity.
          %return
   
   SW(8): ! Speed
          Y = 36 %unless 1<=Y<=36
          TTPUT ('~');   TTPUT ('V');   SBN (Y)
   %end
   
   %routine NEW HP ATTRIBUTE (%integer X, Y)
      %const %string (5) %array ANGLE (0: 7) =  "1,0",  "1,1",   "0,1", "-1,1", "-1,0", "-1,-1", "0,-1", "1,-1"
      %switch AS (0:MAX ATTRIBUTE)
   
      -> AS (X)
   
   AS(0): ! Colour
          Y = 1 %unless 0<=Y<=MAX COLOUR
          CUR COL = Y
          PC = TRUE
          %return
   
   AS(1): ! Line style
          ADD ('L', 'T')
          %if 0<Y<=MAX LINE %start
              TTPUT ('-') %if CURRENT DEV = HP7580
              TTPUT (LINE STYLE MAP (Y))
              TTPUT (',')
              HP OUT REAL (LINE STYLE LEN (Y))
          %finish
          %return
   
   AS(2): ! Char size
          ADD ('S', 'I');   HP OUT REAL (Y/700);   TTPUT (',');   HP OUT REAL (Y/450)
          %return
   
   AS(3): ! Char rot
          ADD ('D', 'I');   ADD STR (ANGLE(((Y+22)//45)&7))
          %return
   
   AS(4): ! Char Quality   (<2 => low quality, 5' tolerance, >2 => highest quality.
          ! Note this only works on fonts 6 - 11.
          %if Y<2 %then LOW QUAL = TRUE %else LOW QUAL = FALSE
          ADD ('C', 'C');  TTPUT ('1')
          %return
   
   AS(5): ! Char Font
          Y = 0 %unless 0 <= Y <= 5
          ADD ('C', 'A')
          TTPUT ('1') %if LOW QUAL # TRUE
          TTPUT (Y + '0')
          ADD ('C', 'S')
          TTPUT ('1') %if LOW QUAL # TRUE
          TTPUT (Y + '0')
          %return
   
   AS(6): ! Char slant
          ADD ('S', 'L')
          TTPUT ('-') %if Y<0
          HP OUT REAL (TAN(MOD(Y) * DtoR)) %if Y#0
          %return
   
   AS(7): ! Intensity
          %return
   
   AS(8): ! Speed
          %if CURRENT DEV # HP7580 %start
              Y = 36 %unless 1<=Y<=36
          %finish %else %start
              Y = 0 %unless 1<=Y<=60
          %finish
          ADD ('V', 'S');   HP OUT NUM (Y)
   %end
   
   %routine RCO JCL
      %integer CUR STREAM
      OPEN OUTPUT (1, "T.GP-B") %and VIEWING = 1 %if VIEWING = 0
      CUR STREAM = OUT STREAM
      SELECT OUTPUT (VIEWING)
      PRINT STRING ("//DOC DEST=GP15,NAME=VAX_".UINFS(1));   NEWLINE
      PRINT STRING ("HP7220T-ECSLIB00ECSLIB  2 ");           NEWLINE
      SET GRAPHICS LIMITS (0, 0, 16000, 11400)
      ADD STR (";SP1;PU;PA0,800;PD;PR0,-100,100,0;SI0.2,0.3;PU;PA0,500;LB   ")
      ! Black pen, Move abs (0, 0), char size 0.2 cm, and draw start mark.
      ADD STR (UINFS(1));   TTPUT (' ');   TTPUT ('(');   ADD STR (UINFS(10))
      ADD STR (")   ");   ADD STR (UINFS(2));   TTPUT (ETX)
      ADD STR (";PU;PA0,300;LB   File ");   ADD STR (OUT FILE NAME)
      ADD STR (" created ");   ADD STR (DATE);   TTPUT (' ');   ADD STR (TIME)
      TTPUT (ETX)
      SELECT OUTPUT (CUR STREAM)
   %end
   
   %return %if COM > 9 %or (DEVICE#3 %and DEVICE#12 %and DEVICE#13)
   LAST COM = COM %if COM # LINE
   -> SW (COM)

SW(0): ! Initialise
       CURRENT DEV = -1
       %for Y = 0, 1, NUM HP %cycle
            CURRENT DEV = Y %if DEV NUMS (Y) = X
       %repeat
       %signal 14, 0 %if CURRENT DEV < 0
       %if NUM PENS(CURRENT DEV)=8 %start
           ! Alter the colour mappings
           SLOT USED (Y) = Y %and SLOT TO USE (Y) = Y %for Y = 5,1,8
       %finish %else %start
           SLOT USED (Y) = 0 %and SLOT TO USE (Y) = DEF SLOT TO USE (Y) %for Y = 5,1,8
       %finish
       ! FRIG for ERCC HP plotter where alternative pen slots should be used -
       %if INTERACTIVE(CURRENT DEV)#TRUE %and X=7220 %start
           SLOT USED (1) = 1;   SLOT USED (2) = 3
           SLOT USED (3) = 4;   SLOT USED (4) = 2
       %finish
!       SET IN (TERMS(CURRENT DEV)) %and SET OUT (TERMS(CURRENT DEV)) %if TERMS(CURRENT DEV)#""
       %if INTERACTIVE (CURRENT DEV) = TRUE %start
           TTMODE (1);   PON
           HP INSTRUCTION ('M');   ADD STR ("0;;10;:"); ! Set output mode
           %if CURRENT DEV = HP7580 %start
               ! Place big plotter in ^S ^Q mode
               HP INSTRUCTION ('I');   ADD STR (";;17;:")
               HP INSTRUCTION ('N');   ADD STR (";19;:")
           %finish
       %finish %else %start
           RCO JCL
       %finish
       %if CURRENT DEV=HP7221 %then TTPUT ('~') %and TTPUT ('_') %else ADD ('I', 'N')
       FULL GRAPHICS LIMITS
       HP PLOT (7, 2, 120); ! Default CHAR size
       HP PLOT (7, 3, 0);   ! Default CHAR rot
       CUR COL = 1;   PC = TRUE
       SX = XL;   SY = YB;   PM = TRUE
       NEW FRAMED = FALSE
       %return

SW(1): ! Terminate
       CHECK PLOTTING and NO TEXT
       FULL GRAPHICS LIMITS
       %if INTERACTIVE(CURRENT DEV)=TRUE %start
           SX = 16000;   SY = 11400;   PM = TRUE
           SX = XL %and SY = YB %if CURRENT DEV = HP7580
           CUR COL = 0;   PC = TRUE
           RESERVE (10)
           CHECK FOR PENDING COLOURS AND MOVES
           ADD ('N', 'R') %if CURRENT DEV = HP7580
           POF
           TTMODE (0)
       %finish %else %start
           X = OUT STREAM
           SELECT OUTPUT (VIEWING)
           PRINT STRING (";PU;PA16000,0;")
           FLUSH OUTPUT
           CLOSE OUTPUT
           SELECT OUTPUT (X)
       %finish
       %return

SW(2): ! Update
       UPDATE
       %return

SW(3): ! Newframe
       NEWFRAME
       %return

SW(4): ! Move Abs
       NEW FRAME %if NEWFRAMED # TRUE
       CHECK PLOTTING AND NO TEXT
       SX = X-XL;   SY = Y-YB;   PM = TRUE
       %return

SW(5): ! Line Abs
       NEW FRAME %if NEW FRAMED # TRUE
       CHECK PLOTTING AND NO TEXT
       RESERVE (30)
       CHECK FOR PENDING COLOURS AND MOVES
       X = X - XL;   Y = Y - YB
       %if CURRENT DEV = HP7221 %then TTPUT ('q') %and MBP (X, Y) %else HP LINE (X, Y)
       SX = X;   SY = Y
       %return

SW(6): ! Character
       NEW FRAME %if NEWFRAMED # TRUE
       PON %if PLOT ACTIVE # TRUE
       %if TEXT MODE # TRUE %start
           CHECK FOR PENDING COLOURS AND MOVES
           %if CURRENT DEV = HP7221 %then TTPUT ('~') %and TTPUT ('''') %else ADD ('L', 'B')
           TEXT MODE = TRUE
       %finish
       TTPUT (X)
       %return

SW(7): ! New attribute
       CHECK PLOTTING and NO TEXT
       %return %if X > MAX ATTRIBUTE
       %if CURRENT DEV = HP7221 %then NEW 7221 ATTRIBUTE (X, Y) %else NEW HP ATTRIBUTE (X, Y)
       %return

SW(8): ! Lower window bounds
       XL = X + XBASE (CURRENT DEV)
       XL = XBASE (CURRENT DEV) %if XL < XBASE (CURRENT DEV)
       YB = Y + YBASE (CURRENT DEV)
       YB = YBASE (CURRENT DEV) %if YB < YBASE (CURRENT DEV)
       %return

SW(9): ! Upper window bounds
       X = X + XBASE (CURRENT DEV)
       X = MAXX (CURRENT DEV) %if X > MAXX (CURRENT DEV)
       Y = Y + YBASE (CURRENT DEV)
       Y = MAXY (CURRENT DEV) %if Y > MAXY (CURRENT DEV)
       SET GRAPHICS LIMITS (XL, YB, X, Y)
%end

%external %routine HP C ARC (%integer RAD, %integer IA, FA)
   %integer OX, OY
   %return %if DEVICE#3 %and DEVICE#12 %and DEVICE#13
   RESERVE (20)
   OX = SX;   OY = SY
   SX = SX + INT (RAD * COS (IA / DtoR));  SY = SY + INT (RAD * SIN (IA / DtoR));   PM = TRUE
   NEWFRAME %if NEWFRAMED # TRUE
   CHECK PLOTTING AND NO TEXT
   CHECK FOR PENDING COLOURS AND MOVES
   %if current dev = HP7221 %start
       TTPUT ('t');   MBN (RAD);   MBA (IA);   MBA (FA)
   %finish %else %start
       ADD ('P', 'D')
       ADD ('A', 'A')
       HP OUT NUM (OX);   TTPUT (',');   HP OUT NUM (OY);   TTPUT (',')
       FA = FA - 360 %if FA > IA
       HP OUT NUM (FA-IA)
       ADD ('P', 'U')
   %finish
   SX = OX;   SY = OY;   PM = TRUE
%end

%external %routine HP AC ARC (%integer RAD, %integer IA, FA)
   %integer OX, OY
   %return %if DEVICE#3 %and DEVICE#12 %and DEVICE#13
   RESERVE (20)
   OX = SX;   OY = SY
   SX = SX + INT (RAD * COS (IA / DtoR));  SY = SY + INT ( RAD * SIN (IA / DtoR));   PM = TRUE
   NEWFRAME %if NEWFRAMED # TRUE
   CHECK PLOTTING AND NO TEXT
   CHECK FOR PENDING COLOURS AND MOVES
   %if CURRENT DEV = HP7221 %start
       TTPUT ('u');   MBN (RAD);   MBA (IA);   MBA (FA)
   %finish %else %start
       ADD ('P', 'D')
       ADD ('A', 'A')
       HP OUT NUM (OX);   TTPUT (',');   HP OUT NUM (OY);   TTPUT (',')
       FA = FA + 360 %if FA<IA
       HP OUT NUM (FA-IA)
       ADD ('P', 'U')
   %finish
   SX = OX;   SY = OY;   PM = TRUE
%end

%external %routine HP CIRCLE (%integer RAD)
   %integer OX
   %return %if DEVICE#3 %and DEVICE#12 %and DEVICE#13
   RESERVE (20)
   %if CURRENT DEV = HP7221 %start
       OX = SX
       SX = SX + RAD;   PM = TRUE
       CHECK FOR PENDING COLOURS AND MOVES
       TTPUT ('t');   MBN (RAD)
       SX = OX;   PM = TRUE
   %finish %else %start
       CHECK FOR PENDING COLOURS AND MOVES
       ADD ('C', 'I');   HP OUT NUM (RAD)
   %finish
%end

%external %routine P CURSOR (%integer %name STATE, X, Y)
   %integer I, S

   %on 1,2,3,4,5,6,7,8 %start
       %signal 14, 4
   %finish

   %routine RAS (%integer %name V)
      ! Read and Skip symbol
      %integer I
      V = 0
      I = TTREAD
      %if I='-' %then S=-1 %and I=0 %else S=1
      %cycle
         V = V*10+(I-'0')
         I = TTREAD
         %exit %unless '0'<=I<='9'
      %repeat
      V = V * S
   %end

   %signal 14, 8 %if INTERACTIVE (CURRENT DEV)#TRUE

   CHECK PLOTTING AND NO TEXT
   CHECK FOR PENDING COLOURS AND MOVES
   S = IN STREAM
   SELECT INPUT (0)
   PROMPT (TO STRING (DEL))
   %if CURRENT DEV = HP7221 %start
       HP INSTRUCTION ('D')
       FLUSH OUTPUT
       RAS (X);   RAS (Y);   RAS (I);   RAS (STATE)
       STATE = I<<4!STATE
       ! State is 'pen up/down flag'<<4! Current pen.
   %finish %else %start
       ADD ('D', 'P')
       %cycle
          ADD ('O', 'S');   TTPUT (';');   FLUSH OUTPUT
          RAS (I)
       %repeat %until I&4#0
       ADD ('O', 'D');   TTPUT (';');   FLUSH OUTPUT
       RAS (X);   RAS (Y);   RAS (STATE)
       STATE = STATE << 4       { for compatability }
   %finish
   POF
   FLUSH OUTPUT
   PROMPT ("Data: ")
   SELECT INPUT (S)
%end

%external %routine HP SPEED (%integer VAL)
   HP PLOT (7, 8, VAL)
%end

%end %of %file
