! EDWIN driver for the DEC GP300 Colour Graphics terminal from Edwin include Device from Edwin include Icodes from Edwin include Iprocs !%from Imp %include Predef !%system %routine %spec changefilesize(%string(31) file,%integer newsize, %integername flag) !%record %format headerf(%integer dataend,datastart,size,filetype,sum,datetime,pstart,start) !%record %format recfor(%integer conad,filetype,datastart,dataend) !%system %routine %spec connect(%STRING (31) filename, %INTEGER access, ! maxbytes,prot, %RECORD (recfor) %NAME r, %INTEGER %NAME flag) !%system %routine %spec disconnect(%STRING (31) filename, %INTEGER %NAME flag) !%routine compress ! %string (255) file name ! %constantinteger lf = 10 ! %record(headerf)%name header ! %record(recfor) rec ! %integer i,ch,marker,j,newbuff,flag ! !%routine data compression ! %constantintegerarray control code(1:3)= 16_1B,16_5B,16_62 ! %integer numchars, this num, tens, hundreds, units ! ! %if marker#0 %start ! %if i-marker>5 %start ! byteinteger(newbuff) = byteinteger(marker) ! byteinteger(newbuff+1) = control code(1) ! byteinteger(newbuff+2) = control code(2) ! numchars = i - marker - 1 ! hundreds = numchars // 100 ! tens = (numchars - hundreds*100) // 10 ! units = (numchars - hundreds*100 - tens*10) ! this num = 3 ! %if hundreds # 0 %start ! byteinteger(newbuff+this num) = hundreds + 16_30 ! this num = this num + 1 ! %finish ! %if hundreds # 0 %or tens # 0 %start ! byteinteger(newbuff+this num) = tens + 16_30 ! this num = this num + 1 ! %finish ! byteinteger(newbuff+this num) = units + 16_30 ! this num = this num + 1 ! byteinteger(newbuff+this num) = control code(3) ! newbuff = newbuff + this num + 1 ! %else ! byteinteger(newbuff+j-marker)=byteinteger(j) %for j=marker,1,i-1 ! newbuff = newbuff + i -marker ! %finish ! %else ! byteinteger(newbuff) = byteinteger(i-1) ! newbuff = newbuff + 1 ! %finish ! marker=0 ! ch= byteinteger(i) !%end ! !I = output stream !select output (viewing) !filename = output name !close output !select output (I) !select output (0) !disconnect (filename,flag) !connect(file name,10,0,0,rec,flag) !header== record(rec_conad) !i = rec_conad + rec_datastart !newbuff = i !ch = byteinteger(i) !marker=0 !%cycle ! i=i+1 ! %if byteinteger(i)=lf %then data compression %and -> end ! %if byteinteger(i)=ch %start ! %if marker = 0 %then marker = i - 1 ! %finishelse data compression !end: !%repeatuntil i = rec_conad + rec_dataend !header_size=newbuff-rec_conad-rec_datastart !header_dataend = header_datastart + header_size !changefilesize(Filename,newbuff-rec_conad-rec_datastart,flag) !%end external routine GP300 alias "EDWIN___M" (integer COM, X, Y) own integer WX, WY switch SW(0:MAX COM) routine SWAP (integer name A, B) integer C C = A; A = B; B = C end const integer LF = 10; const integer DOTS WIDE = 1190 , DOTS HIGH = 1601 const integer LINE MAX = DOTS WIDE//8 + 1 record format LINEF (byte integer array X (0:LINE MAX)) own record (LINEF) array PAGE (0:DOTS HIGH) own byte DRAWN = FALSE own integer resolution = 0 own integer SX = 0, SY = 0 own integer XL = 0, XR = Dots Wide, YB = 0, YT = Dots High routine DRAW PAGE const integer LINE BUFF LEN = (DOTS WIDE+5)//6 + 4 + 2 const integer LIM = LINE MAX // 3 * 3 string (LINE BUFF LEN) LINE BUFF integer P, J, LB, I byte name B byte array name L ! 3-bit inversion table constbyteintegerarray inverse(0:7) = 2_000, 2_100, 2_010, 2_110, 2_001, 2_101, 2_011, 2_111 ! 0 1 2 3 4 5 6 7 ! Set up resolution ttput(16_1B) ttput(16_5B) ttput(16_32) ttput(16_36+2*resolution) ttput(16_68) for I = DEV DATA_MVY, -1, 0 cycle L == PAGE(I)_X LB = ADDR (LINE BUFF) for J = ADDR(L(0)), 3, ADDR(L(LIM)) cycle P = (((BYTE INTEGER(J)<< 8) ! BYTE INTEGER(J+1)) << 8) ! BYTE INTEGER (J+2) BYTE INTEGER (LB + 4) = (P&63); P = P >> 6 BYTE INTEGER (LB + 3) = (P&63); P = P >> 6 BYTE INTEGER (LB + 2) = (P&63); P = P >> 6 BYTE INTEGER (LB + 1) = (P&63) LB = LB + 4 repeat LENGTH(LINE BUFF) = LB - ADDR(LINE BUFF) if LIM#LINE MAX start P = 0 for J = LIM+1, 1, LINE MAX cycle P = (P<<8)!L(J) repeat P = P << (8*(3-(LINE MAX - LIM))) for J = 18, -6, 0 cycle LINE BUFF = LINE BUFF.TO STRING(((P>>J)&63)) repeat finish ! Strip trailing spaces (represented by binary zero) B == LENGTH(LINE BUFF) B = B-1 while B>0 and CHARNO(LINE BUFF, B)=0 ! Add various bits and characters required by Printronix printer for j = addr(line buff)+1,1,lb cycle p = byte integer(j) byte integer(j) = inverse(p&7)<<3 ! inverse(p>>3) ! 64 repeat TTPUT (CHARNO(LINE BUFF,J)) for J = 1, 1, LENGTH(LINE BUFF) TTPUT (LF) FLUSH OUTPUT repeat DRAWN = FALSE end routine DRAW LINE (integer TX,TY) ! This is algorithm 162 in the Collected Algorithms from CACM. ! It computes the code string required to move the pen of a ! digital incremental X-Y plotter from an initial point (SX,SY) to ! a terminal point (TX,TY) 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. integer A,B,D,E,F,T,I,XMOVE,YMOVE,X,Y const byte integer array XCODE(1:16) = 4,0,0,0,0,0,4,0,4,5,5,5,5,5,4,5 const byte 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) ! Move incrementaly over the screen. 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 routine MARK ! make mark in line buffer - represented as a linear bit string byte integer name B B == PAGE(SY)_X(SX>>3) A label to avert a compiler bug: b = b ! (16_80 >> (sx&7) ) end MARK 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 MARK 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 MARK end routine ZERO PAGE integer I PAGE (I) = 0 for I = 0, 1, DOTS HIGH-1 SX = 0 SY = 0 end -> SW (COM) SW(0): ! Initialise DEV DATA_NAME = "a GP300 printer" if X = 30072 start { 72 resolution } DEV DATA_DVX = 500 DEV DATA_DVY = 700 DEV DATA_MVX = 500 DEV DATA_MVY = 700 Resolution = 0 else { 144 resolution } DEV DATA_DVX = 1000 DEV DATA_DVY = 1400 DEV DATA_MVX = 1000 DEV DATA_MVY = 1400 Resolution = 1 finish if VIEWING = 0 start VIEWING = 13 OPEN OUTPUT (VIEWING, "LP#LIS") finish ZERO PAGE DRAWN = FALSE return SW(1): ! Terminate DRAW PAGE if DRAWN = TRUE ttput(27) ttput(16_5B) ttput(16_32) ttput(16_36+resolution*2) ttput(16_6C) ttput(12) ttput(nl) flush output ! compress return SW(2): ! Update return SW(3): ! Newframe DRAW PAGE if DRAWN = TRUE ZERO PAGE DRAWN = TRUE return SW(4): ! Move SX = X SY = Y return SW(5): ! Line DRAW LINE (X,Y) DRAWN = TRUE return SW(6): ! Character signal 14, 14 { to get it done as a software character } SW(8): ! Lower window bounds XL = X; YB = Y return SW(9): ! Upper window bounds XR = X; YT = Y return SW(10): ! ?? return SW(11): ! Was overwrite mode return SW(12): ! Lower box bounds WX = X; WY = Y return SW(13): ! Upper box bounds 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. for COM = Y, -1, WY cycle SX = WX; SY = COM; Draw line (X, SY) repeat return SW(*): ! Ignore all other commands end end of file