! Old EDWIN driver for Cursor Addressable Terminals and line printers. from Edwin include Device from Edwin include Icodes from Edwin include Iprocs from Edwin include Specs from Imp include Ascii const integer MAX X = 131, MAX Y = 23 ! Control for Visual 200 const integer G ON = 'F', G OFF = 'G' const integer G MODE REQ = 16_80 ! The array holds the code symbols for edges with the codes - const integer TOP=1, XLEFT=2, BOT=4, XRIGHT=8 const byte array CODE 200 (0:15) = '_', '_', '_', 'm', '_', 'a', 'l', 'o', '_', 'e', '`', 'c', 's', 'n', 'd', 'b' const byte array CODE 100 (0:15) = '_', '_', '_', 'j', '_', 'x', 'k', 'u', '_', 'm', 'q', 'v', 'l', 't', 'w', 'n' ! Device configuration data - 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 VT131 = 5 const integer MAX CAT = 5 const integer array ERASES (INTERACTS:MAX CAT) = 'v', 'K', '*', FS, 'J', 'J' const integer array CURS U (INTERACTS:MAX CAT) = 'A', DEL, VT, DEL, 'A', 'A' const integer array CURS D (INTERACTS:MAX CAT) = 'B', NL, NL, NL, 'B', 'B' const integer array CURS R (INTERACTS:MAX CAT) = 'C', TAB, FF, TAB, 'C', 'C' const integer array CURS L (INTERACTS:MAX CAT) = 'D', BS, BS, BS, 'D', 'D' const integer array UPS (INTERACTS:MAX CAT) = 'A', 'A', VT, FF, 'A', 'A' const integer array DOWNS (INTERACTS:MAX CAT) = 'B', 'B', NL, VT, 'B', 'B' const integer array RIGHTS (INTERACTS:MAX CAT) = 'C', 'C', CR, DLE, 'C', 'C' const integer array LEFTS (INTERACTS:MAX CAT) = 'D', 'D', BS, BS, 'D', 'D' own integer UP, DOWN, LEFT, RIGHT, CUR U, CUR D, CUR R, CUR L own integer ERASE, MAX SX=79 const byte MAX SY=23 own integer MODEL = -1 own integer XL, YB, 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 const integer TCS = 1; ! True char size. record format COLF (byte integer array COL (0:MAXX)) record format ROWF (record (COLF) array ROW (0:MAXY)) !$IF ERCC compiler $START !%own %record (ROWF) SCREEN !$ELSE $IF IMP77 compiler own record (ROWF) name SCREEN !$FINISH ! The codes are held in SCREEN in the forms - ! 0 + 7 bits of char ! 1 + 3 bits of line style (no longer used!!) + 4 bits of code as above routine ESC PLUS (integer SYM) TTPUT (ESC) TTPUT ('[') if MODEL=VT131 TTPUT (SYM) end routine GMON ! Enter Graphics mode. return if MODE=GON or (MODEL#VISUAL200 and MODEL#VT131) if MODEL=VT131 start TTPUT (ESC); TTPUT ('('); TTPUT ('0') else ESC PLUS (GON) finish MODE = GON end routine GMOFF ! Come out of graphics mode. return if MODE=GOFF or (MODEL#VISUAL200 and MODEL#VT131) if MODEL=VT131 start TTPUT (ESC); TTPUT ('('); TTPUT ('B') else ESC PLUS (GOFF) finish MODE = GOFF end routine DO MOVE integer I switch MS (0:MAX CAT) -> MS (MODEL) MS(Visual 200): ESC PLUS ('Y'); TTPUT (23-SY+32); TTPUT (SX+32) return MS(VT131): I = (24-SY)//10 if I=0 start { Suppress leading 0 } ESC PLUS (REM(24-SY,10)+'0') else ESC PLUS (I+'0') TTPUT (REM(24-SY,10)+'0') finish TTPUT (';') I = SX + 1 if I > 99 start TTPUT ((I//100) + '0') I = Rem (I, 100) TTPUT ((I//10) + '0') TTPUT (Rem(I, 10) + '0') else if I > 9 TTPUT ((I//10) + '0') TTPUT (Rem(I, 10) + '0') else TTPUT (I+'0') finish TTPUT ('H') end external routine Yawn alias "EDWIN___Y" (integer COM, X, Y) own integer WX, WY routine UPDATE DO MOVE if model >= interacts GMOFF 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. const integer LX = 5, RX = 4, UY = 1, DY = 2 integer A,B,D,E,F,T,I,XMOVE,YMOVE,X,Y own integer array XCODE(1:16) = RX,0,0,0,0,0,RX,0,RX,LX,LX,LX,LX,LX,RX,LX own integer array YCODE(1:16) = UY,UY,0,UY,0,DY,DY,DY,DY,DY,0,DY,0,UY,UY,UY ! 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 ADD (integer P) byte name SP { screen pointer return unless 0<=SX<=MAX SX and 0<=SY<=MAX SY SP == SCREEN_ROW(SY)_COL(SX) return if (SP#0 and SP&G MODE REQ = 0) { character already in slot } return if P&(SP&15)=P { nothing new on screen } P = P ! (SP & 15) { OR in lines crossing in other directions. } SP = GMODEREQ ! P { Update the screen map } return if CODE200(P)=95 ! CODE200(P)=95 => nothing to do on Visual 200 or VT131, => optimise. DO MOVE GMON if MODEL=VISUAL200 start TTPUT (CODE 200 (P)) else { %if MODEL=VT131 TTPUT (CODE 100 (P)) finish end routine MOVE (integer X, Y) if X=0 start ADD(XRIGHT); SX = SX + 1; ADD(XLEFT) finish else if X=5 start ADD(XLEFT); SX = SX - 1; ADD(XRIGHT) finish if Y=1 start ADD(TOP); SY = SY + 1; ADD(BOT) finish else if Y=2 start ADD(BOT); SY = SY - 1; ADD(TOP) 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 if SY = TY start { Horisonal Line } ADD (XRIGHT) SX = SX + 1 and ADD (XRIGHT+XLEFT) while SX < TX-1 SX = TX ADD (XLEFT) return finish else if SX = TX start { Vertical line } if SY > TY start ADD (BOT) SY = SY - 1 and ADD (BOT+TOP) while SY > TY+1 SY = TY ADD (TOP) else { SY < TY } ADD (TOP) SY = SY + 1 and ADD (BOT+TOP) while SY < TY-1 SY = TY ADD (BOT) finish return finish { Otherwise the general line code must be used } 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=VISUAL200 or MODEL=VT131) end switch SW(0:MAX COM) signal 14, 0 if INIT#TRUE and COM#0 -> SW(COM) SW(0): ! Initialise MAX SX = 79 DEV DATA_DVY = 23 DEV DATA_MVY = 23 DEV DATA_ARF = 45 DEV DATA_NUM CHAR SIZES = 255 DEV DATA_NUM CHAR ROTS = 255 X = 131 if X=220 { VT220 = VT100 for present } if X=200 start DEVICE DATA_NAME = "a Visual 200 terminal" MODEL = VISUAL 200 else if X=131 DEVICE DATA_NAME = "a VT100 terminal" MODEL = VT131 TTPUT (esc); TTPUT ('['); TTPUT ('?'); TTPUT ('3'); TTPUT ('h') DEV DATA_ARF = 30 MAX SX = 130 else signal 14, 0 finish DEV DATA_DVX = MAX SX DEV DATA_MVX = MAX SX ERASE = ERASES (MODEL) 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) SCREEN == NIL SCREEN == NEW (SCREEN) SCREEN = 0 TTMODE (1) TTPUT (ESC) and TTPUT ('(') and TTPUT ('0') if MODEL=VT131 { enable graphics characters } INIT = TRUE return SW(1): !Terminate if MODEL = VT131 start TTPUT (ESC); TTPUT ('('); TTPUT ('B') { Default char set } TTPUT (esc); TTPUT ('['); TTPUT ('?'); TTPUT ('3'); TTPUT ('l') finish SX = 0; SY = 0 { -> bottom of screen } UPDATE DISPOSE (SCREEN) TTMODE (0) return SW(2): ! Update UPDATE return SW(3): ! New frame X = 0 ESC PLUS ('H') if MODEL=VT52 if MODEL=VT131 then ESC PLUS ('2') and TTPUT (ERASE) c else ESC PLUS (ERASE) Y = 22 UPDATE SCREEN = 0 Y = 0 -> SW(4) SW(5): ! Line Abs DRAW LINE (X, Y) SW(4): ! Move Abs VIS = False and return unless 0<=X<=MAX SX and 0<=Y<=MAX SY SX = X; SY = Y DO MOVE VIS = TRUE DIF = TRUE return SW(6): ! Character return unless VIS=TRUE GMOFF TTPUT (X) X = 0 if X = ' ' SCREEN_ROW(SY)_COL(SX) = X SX = SX + TCS VIS = FALSE if SX>XR DIF = TRUE Inquire Position (x, y) Clip (x, y, 0) return SW(7): ! Attribute Change return SW(8): ! Set lower window bounds XL = X; YB = Y 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 SW(12): ! Lower Box bounds WX = X; WY = Y return SW(13): ! Upper Box bounds & Draw the box SWAP (WX, X) if WX > X SWAP (WY, Y) if WY > Y return if WX > XR or X < XL or WY > YT or Y < YB WX = XL if WX < XL WY = YB if WY < YB X = XR if X > XR Y = YT if Y > YT ! Box now clipped into the screen. Yawn (4, wx, wy) Yawn (5, wx, y) Yawn (5, x, y) Yawn (5, x, wy) Yawn (5, wx, wy) return SW(*): end external routine VCURSOR alias "EDWIN___Y_REQ" (integer name CH,X,Y) routine ESCAPE TTPUT (ESC) if MODEL=VT131 start TTPUT ('[') TTPUT ('1') finish end signal 14,8 if MODEL<INTERACTS TTPUT (7) DO MOVE; FLUSH OUTPUT; MODE = 0; ! Update (in line). X = SX; Y = SY; cycle CH = TTGET exit if CH >= ' '; ! Key hit, => return continue if CH#ESC CH = TTGET; ! The significant character of the ESC sequence. if MODEL=VT131 start CH = TTGET until 'A'<=CH<='D' finish if CH=CUR U start Y =Y+1 if Y<23 ESCAPE; TTPUT (UP) finish else start if CH=CUR R start X =X+1 if X<MAX SX ESCAPE; TTPUT (RIGHT) finish else start if CH=CUR L start X =X-1 if X>0 ESCAPE; TTPUT (LEFT) finish else start if CH=CURD start Y =Y-1 if Y>0 ESCAPE; TTPUT (DOWN) finish else continue finish finish finish FLUSH OUTPUT repeat end end of file