! 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 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