! EDWIN driver for baby Cursor Addressable Terminals with no memory. %external %routine %spec SIGNAL (%integer E, S, X) %external %routine %spec TTMODE (%integer PARM) %external %integer %fn %spec TTGET %external %routine %spec TTPUT (%integer CH) %external %routine %spec FLUSH OUTPUT %external %integer %spec DEVICE ! Control characters %const %integer ESC = 27, DEL = 127, FF = 12, TAB = 9, BS = 8 %const %integer ERASE 550 = 'K' %const %integer ERASE 200 = 'v' %const %integer ERASE 120 = '*' %own %integer ERASE SCREEN = 'v' ! Screen information %own %integer DEV = 200; ! 200 52 or 550 or 120 %own %integer SX = 0; !Current device position %own %integer SY = 0 %own %integer XR = 79; !Right hand side of device window %own %integer YT = 23; ! Top of dev. window. %own %integer VIS = 0; !0 if CVP inside VW %own %byte %integer STYLE = 0, FONT = 0 %own %integer CU = 0, CD = 0, CL = 0, CR = 0; ! Cursor control chars (set at init) %const %byte %integer %array AS(0:7) = '*', '-', '#', '+', '*' (*) %const %integer TCS = 1; ! True char size. %own %integer UP = 'A', DOWN = 'B', LEFT = 'D', RIGHT = 'C' %routine DO MOVE ! Move to current position TTPUT (ESC) %if DEV=200 %start TTPUT('Y'); TTPUT(23-SY+32); TTPUT(SX+32) %finish %else %start %if DEV=550 %start TTPUT('Y'); TTPUT(SX+32); TTPUT(ESC); TTPUT('X'); TTPUT(23-SY+32) %finish %else %start TTPUT ('='); TTPUT (32+23-SY); TTPUT (SX+32) %finish %finish %end %dynamic %routine KITTEN (%integer COM, X, Y) %switch SW(0:15) %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. %byte %integer %name SP DO MOVE %if DEV=550 %and STYLE=0 %then TTPUT (ESC) %and TTPUT(DEL) %c %else TTPUT (AS(STYLE)) SX = SX + 1 %if X=0 SX = SX - 1 %if X=5 SY = SY + 1 %if Y=1 SY = SY - 1 %if Y=2 %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) %end %return %unless DEVICE=12 COM = COM & 15 -> SW(COM) SW(0): ! Initialise TTMODE (1) DEV = X ERASE SCREEN = ERASE 550 %if DEV = 550 ERASE SCREEN = ERASE 200 %if DEV = 200 ERASE SCREEN = ERASE 120 %if DEV = 120 ! Set the cursor control characters for device %if DEV=200 %start CU = 'A'; CD = 'B'; CL = 'D'; CR = 'C' %finish %else %start %if DEV=550 %start CU = DEL; CD = NL; CL = BS; CR = TAB %finish %else %start CU = 'K'&31; CD = NL; CL = BS; CR = FF UP = CU; DOWN = CD; LEFT = BS; RIGHT = CR %finish %finish %return SW(1): !Terminate SX = 0 SY = 0 SW(2): ! Update DO MOVE FLUSH OUTPUT TTMODE (0) %if COM=1 %return SW(3): ! New frame TTPUT (30) %if DEV=120 TTPUT (ESC) TTPUT (ERASE SCREEN) TTPUT (0) %for Y=0,1,20 FLUSH OUTPUT X = 0 Y = 0 -> SW(4) SW(5): ! Line Abs DRAW LINE (X, Y) SW(4): ! Move Abs SX = X SY = Y DO MOVE VIS = 0 %return SW(6): ! Character %return %if VIS#0 TTPUT (X) SX = SX + TCS VIS = 1 %if SX>XR %return SW(7): ! Attribute Change STYLE = Y&7 %if X = 1 %return SW(8): ! Set lower window bounds %return SW(9): ! Set upper device window bounds XR = X XR = 79 %if XR>79 YT = Y ! Ignore the YT restriction, as terminal will scroll. %return SW(*): %end %dynamic %routine KCURSOR (%integer %name CH,X,Y) signal (14, 8, dev) TTPUT (7); TTPUT (7) DO MOVE FLUSH OUTPUT X = SX; Y = SY; %cycle CH = TTGET %exit %if CH >= ' '; ! Key hit, => return %continue %if CH#ESC %and DEV=200 CH = TTGET %if DEV=200; ! The significant character of the ESC sequence. %if CH=CU %start Y =Y+1 %if Y<23 TTPUT (ESC) %unless DEV=120; TTPUT (UP) %finish %else %start %if CH=CR %start X =X+1 %if X<79 TTPUT (ESC) %unless DEV=120; TTPUT (RIGHT) %finish %else %start %if CH=CL %start X =X-1 %if X>0 TTPUT (ESC) %unless DEV=120; TTPUT (LEFT) %finish %else %start %if CH=CD %start Y =Y-1 %if Y>0 TTPUT (ESC) %unless DEV=120; TTPUT (DOWN) %finish %else %continue %finish %finish %finish FLUSH OUTPUT %repeat %end %end %of %file