! EDWIN driver for Cursor Addressable Terminals and line printers. ! For systems where memory is a precious resource, the following constants ! can be set to -1, and the driver can still drive most CATs. %include "ecsc03.subsyss_iospecs" %const %integer MAX X = 131, MAX Y = 63 %external %routine %spec TTMODE (%integer WHAT) %external %integer %fn %spec TTGET %external %routine %spec TTPUT (%integer CH) %external %routine %spec FLUSH OUTPUT %external %integer %spec DEVICE %const %integer TRUE = 0, FALSE = 1 ! Control characters %const %integer BS = 8, TAB = 9, VT = 11, FF = 12, CR = 13, DC1 = 17 %const %integer DLE = 16, ESC = 27, FS = 28, RS = 30, DEL = 127 ! Control for Visual 200s %const %integer G ON = 'F', G OFF = 'G' %const %integer G MODE REQ = X'80' ! The array holds the code symbols for edges with the codes - %const %integer TOP=1, XLEFT=2, BOT=4, XRIGHT=8 %const %byte %integer %array CODE (0:15) = 'a'-2, 'a'-2, 'a'-2, 'm', 'a'-2, 'a', 'l', 'o', 'a'-2, 'e', '`', 'c', 's', 'n', 'd', 'b' ! Device configuration data - %const %integer MIN CAT = -3 %const %integer Wide LP = -3 %const %integer Narr LP = -2 %const %integer Video = -1 %const %integer INTERACTS = 0; ! Terminal >= interacts => terminal has Graphics capabitility. %const %integer Visual 200 = 0 %const %integer Bantam 550 = 1 %const %integer Soroc 120 = 2 %const %integer HazeltineE = 3 %const %integer VT52 = 4 %const %integer MAX CAT = 4 %const %integer %array MODELS (MIN CAT:MAX CAT) = 'L', 72, 'V', 200, 550, 120, 'E', 52 %const %integer %array MAXSXS (MIN CAT:MAX CAT) = 131, 72, 79, 79, 79, 79, 79, 79 %const %integer %array MAXSYS (MIN CAT:MAX CAT) = 63, 63, 23, 23, 23, 23, 23, 23 %const %integer %array ERASES (INTERACTS:MAX CAT) = 'v', 'K', '*', FS, 'w' %const %integer %array CURS U (INTERACTS:MAX CAT) = 'A', DEL, VT, DEL, 'A' %const %integer %array CURS D (INTERACTS:MAX CAT) = 'B', NL, NL, NL, 'B' %const %integer %array CURS R (INTERACTS:MAX CAT) = 'C', TAB, FF, TAB, 'C' %const %integer %array CURS L (INTERACTS:MAX CAT) = 'D', BS, BS, BS, 'D' %const %integer %array UPS (INTERACTS:MAX CAT) = 'A', 'A', VT, FF, 'A' %const %integer %array DOWNS (INTERACTS:MAX CAT) = 'B', 'B', NL, VT, 'B' %const %integer %array RIGHTS (INTERACTS:MAX CAT) = 'C', 'C', CR, DLE, 'C' %const %integer %array LEFTS (INTERACTS:MAX CAT) = 'D', 'D', BS, BS, 'D' %own %integer UP, DOWN, LEFT, RIGHT, CUR U, CUR D, CUR R, CUR L %own %integer ERASE, MAX SX, MAX SY %own %integer MODEL = M'NO' %own %integer YT, XR ; ! Current Max Window bound ! device information %own %integer MODE = 0; ! 0 if alphamode, 1 if Graph mode, -1 if unknown %own %integer SX = 0, SY = 0;! Current device position %own %byte VIS = TRUE; ! TRUE if the current position is in the device window %own %byte DIF = TRUE; ! TRUE if an UPDATE has just been done %own %byte INIT = FALSE; ! Indicates if the driver is initialised %own %byte STYLE = 0, FONT = 0 %const %integer dim = '4', bright = '3'; ! Intensity for Visual 200 %const %byte %integer %array AS(0:7) = '*', '-', '#', '+', '*' (*) %const %integer TCS = 1; ! True char size. %record %format COLF (%byte %integer %array COL (0:MAXX)) %own %record (COLF) %array SCREEN (0:MAXY) ! The codes are held in SCREEN in the forms - ! 0 + 7 bits of char ! 1 + 3 bits of line style + 4 bits of code as above %routine G M ON ! Enter Graphics mode. %return %if MODE=GON %or MODEL#Visual 200 TTPUT (ESC) TTPUT (GON) MODE = GON %end %routine G M OFF ! Come out of graphics mode. %return %if MODE=GOFF %or MODEL#Visual 200 TTPUT (ESC) TTPUT (GOFF) MODE = GOFF %end %routine DO MOVE %switch MS (0:MAX CAT) %return %unless INTERACTS <= MODEL <= MAX CAT -> MS (MODEL) MS(Visual 200): MS(VT 52): GMOFF TTPUT (ESC); TTPUT('Y'); TTPUT(23-SY+32); TTPUT(SX+32) %return MS(Bantam 550): TTPUT (ESC); TTPUT('Y'); TTPUT(SX+32) TTPUT (ESC); TTPUT('X'); TTPUT(23-SY+32) %return MS(Soroc 120): TTPUT(ESC); TTPUT ('='); TTPUT(32+23-SY); TTPUT(SX+32) %return MS(HazeltineE): TTPUT (ESC); TTPUT (DC1) %if SX=0 %then TTPUT ('`') %else TTPUT (SX) TTPUT ('w' - SY) %end %external %routine CATS (%integer COM, X, Y) %routine UPDATE %byte %integer SP %integer I, J, K, ST ! Draw the screen %if model < interacts %and maxx>=0 %and DIF=TRUE %start %for I=YT,-1,0 %cycle %for J=XR,-1, 0 %cycle %exit %if SCREEN(I)_COL(J)#0 %repeat %for K=0,1,J %cycle SP = SCREEN (I)_COL(K) SP = ' ' %if SP=0 %if SP&GMODE REQ#0 %start; ! Line ST = SP>>4&7; ! Line style TTPUT (AS(ST)) %finish %else TTPUT (SP) %repeat TTPUT (13) TTPUT (NL) %if I>0 %repeat TTPUT (FF) %if YT<63 %and model=wide LP %finish %else %start DO MOVE %if model >= interacts %finish FLUSH OUTPUT MODE= 0 DIF = FALSE %end %routine SWAP (%integer %name A, B) %integer C C = A; A = B; B = C %end %routine DRAW LINE (%integer TX,TY) ! This is algorithm 162 in the Collected Algorithms from CACM. ! ! XYMOVE computes the code string required to move the pen of a ! digital incremental X-Y plotter from an initial point (XZ,YZ) to ! a terminal point (XN,YN) by the "best" approximation to the ! straight line between the points. The permitted elemental pen ! movement is to an adjacent point in a plane Cartesian point latice, ! diagonal moves permitted. ! The Algorithm has been modded to draw lines on Visual 200s. ! Using horisontal & vertical lines where possible, otherwise '+'. ! or on other terminals by filling character positions. %integer A,B,D,E,F,T,I,XMOVE,YMOVE,X,Y %own %integer %array XCODE(1:16) = 4,0,0,0,0,0,4,0,4,5,5,5,5,5,4,5 %own %integer %array YCODE(1:16) = 1,1,0,1,0,2,2,2,2,2,0,2,0,1,1,1 ! PY,PX+PY,PX,PX+PY,PX,PX+NY,NY,PX+NY,NY,NY+NX,NX,NX+NY,NX,NX+PY,PY,NX+PY %routine MOVE (%integer X,Y) %const %integer SPLOGE = 15 ; ! All directions set for non v200 terms. %routine ADD (%integer P) %byte %integer %name sp %if maxx>=0 %start SP == SCREEN (SY)_COL(SX) %return %if SP#0 %and SP&G MODE REQ = 0 ! Return if a character is already in this slot. P = P ! SP & 15; ! OR in lines crossing in other drns. SP = GMODE REQ ! (STYLE << 4) ! P %finish %return %if MODEL nothing to do on Visual 200, => optimise. %if model >= interacts %start do move %if STYLE#0 %then TTPUT (AS(STYLE)) %else %start %if model=Bantam 550 %then TTPUT (ESC) %and TTPUT(DEL) %else %start %if model=Visual 200 %then GMON %and TTPUT (CODE(P)) %else TTPUT ('*') %finish %finish %finish %end %if STYLE#0 %or model#Visual 200 %then %start ADD (SPLOGE) %if X=0 %then SX = SX + 1 %else %start SX = SX - 1 %if X=5 %finish %if Y=1 %then SY = SY + 1 %else %start SY = SY - 1 %if Y=2 %finish %finish %else %start %if X=0 %then ADD(XRIGHT) %and SX=SX+1 %and ADD(XLEFT) %else %start ADD(XLEFT) %and SX=SX-1 %and ADD(XRIGHT) %if X=5 %finish %if Y=1 %then ADD(TOP) %and SY=SY+1 %and ADD(BOT) %else %start ADD(BOT) %and SY=SY-1 %and ADD(TOP) %if Y=2 %finish %finish %end SWAP (SX, TX) %and SWAP (SY, TY) %if SX > TX; ! Optimise mode. MOVE (SX, SY) %and %return %if SX=TX %and SY=TY A = TX - SX B = TY - SY D = A + B T = B - A I = 0 %if B>=0 %then I=2 %if D>=0 %then I=I+2 %if T>=0 %then I=I+2 %if A>=0 %then I=8-I %else I=I+10 A = -A %if A<0 B = -B %if B<0 F = A + B D = B - A %if D>=0 %then T=A %and D=-D %else T= B E = 0 XMOVE = XCODE (I-1) YMOVE = YCODE (I-1) X = XCODE (I) Y = YCODE (I) %cycle A = D + E B = T + E + A %if B>=0 %start E = A F = F - 2 MOVE (X, Y) %finish %else %start E = E + T F = F - 1 MOVE (XMOVE, YMOVE) %finish %exit %if F<=0 %repeat MOVE (TX, TY) %unless Model=Visual 200 %and STYLE=0 %end %switch SW(0:9) %return %unless 7<=DEVICE<=10 %and 0<=COM<=9 %signal 14, 0 %if INIT#TRUE %and COM#0 -> SW(COM) SW(0): ! Initialise X = X & 95 %if X<127; ! Upper case characters only MODEL = M'NO' %for COM = MIN CAT, 1, MAX CAT %cycle MODEL = COM %and %exit %if X=MODELS(COM) %repeat %signal 14, 0 %if model=M'NO' ERASE = ERASES (MODEL) MAXSX = MAXSXS (MODEL) MAXSY = MAXSYS (MODEL) %if model>=interacts %start CUR U = CURS U (MODEL) CUR D = CURS D (MODEL) CUR R = CURS R (MODEL) CUR L = CURS L (MODEL) UP = UPS (MODEL) DOWN = DOWNS (MODEL) RIGHT = RIGHTS (MODEL) LEFT = LEFTS (MODEL) %finish SCREEN (Y) = 0 %for Y=0,1,MAXY TTMODE (1) %unless model < interacts INIT = TRUE %return SW(1): !Terminate TTPUT (ESC) %and TTPUT (bright) %if MODEL=Visual 200 SX = 0; SY = 0 UPDATE TTMODE (0) %unless MODEL=INTERACTS %start TTPUT (RS) %if MODEL=SOROC 120 TTPUT (ESC) TTPUT (ERASE) TTPUT (0) %for Y=0,1,20 FLUSH OUTPUT %finish SCREEN(Y) = 0 %for Y=0,1,MAXY X = 0; Y = 0 -> SW(4) SW(5): ! Line Abs DRAW LINE (X, Y) SW(4): ! Move Abs SX = X; SY = Y DO MOVE %unless MODEL= 0 SX = SX + TCS VIS = FALSE %if SX>XR DIF = TRUE %return SW(7): ! Attribute Change STYLE = Y&7 %if X = 1 %if MODEL = Visual 200 %start FONT = Y %if X = 5 %if X = 7 %start; ! Intensity TTPUT (ESC) %if Y>=4 %then TTPUT (bright) %else TTPUT (dim) %finish %finish %return SW(8): ! Set lower window bounds %return SW(9): ! Set upper device window bounds XR = X XR = MAX SX %if XR>MAX SX YT = Y YT = MAX SY %if YT>MAX SY %return %end %dynamic %routine VCURSOR (%integer %name CH,X,Y) %signal 14,8 %if MODEL= ' '; ! Key hit, => return %continue %if CH#ESC %and model=Visual200 CH = TTGET; ! The significant character of the ESC sequence. %if CH=CUR U %start Y =Y+1 %if Y<23 TTPUT (ESC); TTPUT (UP) %finish %else %start %if CH=CUR R %start X =X+1 %if X<79 TTPUT (ESC); TTPUT (RIGHT) %finish %else %start %if CH=CUR L %start X =X-1 %if X>0 TTPUT (ESC); TTPUT (LEFT) %finish %else %start %if CH=CURD %start Y =Y-1 %if Y>0 TTPUT (ESC); TTPUT (DOWN) %finish %else %continue %finish %finish %finish FLUSH OUTPUT %repeat %end %end %of %file