! EDWIN driver for the Masscomp

from EDWIN include Device, Icodes

record format Point fm (integer x, y)

dynamic routine spec DD INIT alias "EDWIN_DD_INIT"(integer name x,y)
dynamic routine spec DD TERM alias "EDWIN_DD_TERM"
dynamic routine spec DD UPDATE alias "EDWIN_DD_UPDATE"
dynamic routine spec DD CLEAR alias "EDWIN_DD_CLEAR"
dynamic routine spec DD COL  alias "EDWIN_DD_COL"  (integer Col)
dynamic routine spec DD MODE alias "EDWIN_DD_MODE" (integer Mode)
dynamic routine spec DD FILL alias "EDWIN_DD_FILL" (integer Mode)
dynamic routine spec DD DOT  alias "EDWIN_DD_DOT"  (integer X, Y)
dynamic routine spec DD LINE alias "EDWIN_DD_LINE" (integer OX, OY, NX, NY)
dynamic routine spec DD TEXT alias "EDWIN_DD_TEXT" (integer X, Y, byte name T)
dynamic routine spec DD RECT alias "EDWIN_DD_RECT" (integer LX, LY, HX, HY)
dynamic routine spec DD POLY alias "EDWIN_DD_POLY" (integer NP,
                                 integer name xpts,ypts)

own integer SX = 0
own integer SY = 0
own integer XL = 0
own integer YB = 0
own integer XR = 32767
own integer YT = 20479
own byte Smode=0, CCol = 1,CMode = 0

external routine Masscomp alias "EDWIN___B" (integer Com, X, Y)
   own string (127) text = ""
   own short Counter = 0
   own integer WX, WY, Nlines = 0
   record format Data Fm (record (point fm) p, record (Data Fm) name Next)
   own record (Data fm) name Point List == 0
   own record (Data fm) name Next point == 0
   switch SW(0:15)
   switch AS(0:att maximum)

!   %include "Polyfill.OPS"

   routine SWAP (integer name  A, B)
      integer C
      C = A;   A = B;   B = C
   end

   routine draw lines
      record (Data fm) name PP
      integer array xpts,ypts(1:nlines+1)
      integer i
      return if Point List == Nil
      if nlines <= 1 start
          DD Dot (point list_p_x, point list_p_y)
      else if nlines = 2
          DD Line (point list_p_x, point list_p_y,
                   point list_next_p_x, point list_next_p_y)
      else
          pp == point list
          for I = 1, 1, Nlines cycle
             xpts(i) = pp_p_x
             ypts(i) = pp_p_y
             pp == pp_next
          repeat
          nlines = nlines + 1
          xpts(nlines) = xpts(1)
          ypts(nlines) = ypts(1)
          DD POLY (nlines, Xpts(1),Ypts(1))
      finish
      nlines = 0
   end

   routine print text
      text = text.tostring (0)
      dd text (sx, sy, byte(addr (text)+1))
      text = ""
   end

   print text if text # "" and com # 6
   draw lines if nlines # 0 and (com = 10 or COM < 5)
   counter = counter + 1
   if counter & 64 # 0 start
      counter = 0
!      %signal 13,0 %if char = Etx %or char = Del
    finish

!   select output(0)
!   print string("Device driven with ".itos(com,0).itos(x,3).itos(y,3))
!   newline

   -> SW (Com)

SW(0): ! Initialise
       Point List == New (point list)
       point List_next == Nil
       Dev Data_Name = "a Masscomp Graphics Processor"
       DD INIT(Dev Data_DVX,Dev Data_DVY)
       Dev Data_MVX = Dev Data_DVX
       Dev Data_MVY = Dev Data_DVY
       XR = Dev Data_DVX
       YT = Dev Data_DVY
       return

SW(1): ! Terminate
       DD TERM
       return

SW(2): ! Update
       DD UPDATE
       return

SW(3): ! New frame
       DD CLEAR
       return

SW(4): ! Move
       SX = X;   SY = Y
       return

SW(5): ! Line
       if Smode = 2 start
           DD Dot (x, y)
       else if Smode = 0
           DD Line (sx, sy, x, y)
       else
           if Nlines = 0 start
               point list_p_x = sx;   point list_p_y = sy
               Next point == point list
               Nlines = 1
           finish
           return if x=sx and y=sy
           Nlines = Nlines + 1
           if Next point_next == Nil start
               Next point_next == New (Next point)
               Next point      == Next point_next
               Next point_next == Nil
           else
               Next point == next point_next
           finish
           next point_p_x = x;   next point_p_y = y
       finish
       sx = x;   SY = y
       return

SW(6): ! Char
       length(text) = length(text) + 1
       charno(text,length(text)) = x
       print text if length(text) = 126
       return

SW(7): ! Attribute
       if 0<=x<=Att maximum start
           -> as(x)
AS(0): ! Colour
       Y = 1 unless 0 <= y <= 15
       CCol = y
       DD Col (CCol)
       return
AS(1): ! Line style
       Y = 0 unless 0<=y<=4
       return
AS(2): ! Character Size
       return
AS(9): ! Overwrite mode
       Y = 0 unless 0<=y<=4
       CMode = y
       DD Mode (y)
       return
AS(10): ! Shade mode
        Smode = Y
        DD Fill(Smode)
        return
       finish
AS(*): { Ignore the rest }
       return

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
        Y = X
        X = Att Colour mode
        -> SW (7)

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.
        if Smode = 0 start
            Masscomp (4, wx, wy)
            Masscomp (5, x, wy)
            Masscomp (5, x, y)
            Masscomp (5, wx, y)
            Masscomp (5, wx, wy)
        else
            DD Rect (wx, wy, x, y)
        finish
        return

SW(14): ! Circle
        return

SW(*):
end

external routine draw dots alias  "EDWIN_DRAW_DOTS" ( -
                 integer lx,ly,hx,hy,gap)
   integer active,i
   integer lx1,ly1,hx1,hy1,x,y,y1,x1
   integer smode = Cmode, scolour = CCol

   from edwin include specs

   Cmode = 0 ; CCol = 1
   DD mode(CMode) ; DD Col(CCol)

   lx1 = lx ; ly1 = ly ; hx1 = hx ; hy1 = hy
   !
   ! draw vertical lines
   !
   lx = hx1 ; ly = hy1
   map to device coords(lx,ly)
   y1 = ly
   lx = lx1 ; ly = ly1
   map to device coords(lx,ly)
   y = ly
   lx = lx1 ; ly = ly1
   while lx <= hx1 cycle
      hx = lx ; hy = ly
      map to device coords(hx,hy)
      DD LINE(hx,y,hx,y1)
      lx = lx + gap
   repeat
   !
   ! put black boxes on top
   !
   CCol = 0 ; DD Col(CCol)
   lx = lx1 ; ly = ly1
   while ly < hy1 cycle
      hy = ly ; lx = lx1
      map to device coords(lx,hy) ; x = hx1
      y = ly + gap
      map to device coords(x,y)
      DD RECT(lx,hy + 1,x + 1,y - 1)
      ly = ly + gap
   repeat

   !
   ! put the old values in again
   !
   Cmode = smode ; DD mode(cmode)
   CCol = scolour ; DD col(CCol)
end

end of file