    ! EDWIN driver for Oric MCP-40 4 colour plotter

    ! 1-APR-1987 ANY Written

    from Edwin include Device
    from Edwin include Icodes
    from Edwin include Specs

    ! Control characters
    const integer cr = 13
    const integer DC1 = 17
    const integer DC2 = 18
    const integer esc = 27
    const integer sp = ' '
    const integer Min = '-'
    const integer Comma = ','

    ! Plotter information
    own integer CX = 0;        !Current device position
    own integer CY = 0
    own integer PX = 0       {proper device position}
    own integer PY = 0
    own integer XL = 0
    own integer XR = 679;     !Right hand side of device window
    own integer YB = 0
    own integer YT = 479
    own integer Colour = 1
    own integer Pen Colour = 1
    own integer Char Size = 2 {MCP-40 Size + 1, use 0 as "too wee, don't bother"}
    own integer Edwin Char Size = 12
    own integer Max X = 0
    const integer Yes=1,No=0
    own integer Drew Last = No
    own integer Char Rot = 1
    own integer Edwin Char Rot = 0

    routine Newln
       TTPut(CR)
    end

    routine TTString(string (255) Thing)
       integer I
       for I=1,1,Length(Thing) cycle
          TTPut(Charno(Thing,I))
       repeat
    end

    routine Sort Position
       if PX # CX or PY # CY start
          TTString("M".ITOS(PY,0).Comma)
          if PX>0 then TTPut(Min)
          TTString(ITOS(PX,0).CR)
          CX = PX
          CY = PY
       finish
    end

    routine Check Draw
       if Drew Last = Yes start
          TTput(CR)
          Drew Last = No
       finish
    end

    routine update
       flush output
    end

    external routine Oric 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

       routine CHANGE ATTRIBUTE (integer WHICH, TO)
          integer i
          switch AS(0:ATT MAXIMUM)
          -> AS(WHICH)

    AS(att Colour):
          if To > 4 then To = 1
          if To = Colour then return
          Colour = To
          if Colour # 0 start
             TTPut('C')
             TTPut(Colour+'0'-1)
             Newln
          finish
          return

    AS(att line style):
          TTPut('L')
          if To = 0 or To = 2 start
             TTPut('0')
          else if To = 1
             TTput('2')
          else if To = 3
             TTput('7')
          else if To = 4
             TTString(ITOS(15,0))
          finish
          Newln
          return

    AS(att char size):
          Edwin Char Size = To
    Write(Edwin Char Size,0)
    Newline
          I = Edwin Char Size//6
          if I > 63 then I = 63
          if I # Char Size start
             Char Size = I
             if Char Size > 0 start
                TTPut('S')
                TTString(Itos(Char Size-1,0))
                Newln
             finish
          finish
          return

    AS(Att Char Rot):
          if To <=45 or To > 315 start
             I = 1
          else if 45 < To <=135
             I = 0
          else if 135 < To <= 225
             I = 3
          else if 225 < To <= 315
             I = 2
          finish
          if Char Rot # I start
             Char Rot = I
             TTPut('Q')
             TTPut(Char Rot+'0')
             Newln
          finish
          return

    AS(att char font):
          return

    AS(att colour mode):
          return

    AS(*): ! Ignore all other attributes
       end

    Write(COM,1)
    Write(X,1)
    Write(Y,1)
    Newline

       -> SW(COM)

    SW(0): ! Initialise
          dev data_name = "an MCP-40 Colour Printer"
          dev data_dvx = 679
          dev data_dvy = 479
          dev data_Mvx = 999
          dev data_Mvy = 479
          dev data_Max Colour = 4
          dev data_Max Styles = 4
          dev data_Num Char Rots = 3
          dev data_Num Char Sizes = 255
          dev data_Units Per Cm = 50
          dev data_X Units Per Cm = 50
          dev data_Y Units Per Cm = 50
          Set Device("EDWIN_MCP40")
          TTString(DC1.CR.DC2."I".CR."L0".CR."S1".CR."C0".CR."Q1".CR)
          return

    SW(1): !Terminate
          Check Draw
          TTString("M0,")
          if MaxX > 0 then TTPut(Min)
          TTString(Itos(MaxX,0))  {Move to end of Plot}
          Newln
          TTString("L0")
          Newln
          TTstring("S1")                {40 Col Mode}
          Newln
          TTstring("C0")
          Newln
          TTstring("Q0")
          Newln
          TTPut(DC1)
          TTString(NL.NL.NL.NL)
          flush output
          return

    SW(2): ! Update
           Check Draw
           Sort Position
           flush output
           return

    SW(3): ! New frame
          Check Draw
          TTString("M0,")
          if MaxX > 0 then TTPut(Min)
          TTString(Itos(MaxX,0).CR)  {Move to end of Plot}
          TTString("I".CR)
          TTString("M0,-40".CR)
          TTString("I".CR)
          CX = 0
          CY = 0
          PX = 0
          CX = 0
          MaxX = 0
          return

    SW(4): ! Move Abs
          Check Draw
          PX = X
          PY = Y
          if PX > MaxX then MaxX = PX
          return

    SW(5): ! Line Abs
          if Colour # 0 start
             if Drew Last = Yes start
                TTPut(Comma)
             else
                Sort Position
                TTPut('D')
             finish
             Drew Last = Yes
             TTString(Itos(Y,0).Comma.Min.Itos(X,0))
             CX=X
             CY=Y
          finish
          PX=X
          PY=Y
          if X > MaxX then MaxX = X
          return

    SW(6): ! Character
          Check Draw
          if Char Rot = 1  start
             CX = CX + (Char Size)*6
             PX = PX + Edwin Char Size
          else if Char Rot = 2
             CY = CY - (Char Size)*6
             PY = PY - Edwin Char Size
          else if Char Rot = 3
             CX = CX - (Char Size)*6
             PX = PX - Edwin Char Size
          else if Char Rot = 0
             CY = CY + (Char Size)*6
             PY = PY + Edwin Char Size
          finish
          if PX > MAxX then MaxX = PX
          if Char Size = 0 then return
          Sort Position
          TTPut('P')
          TTPut(X)
          Newln
          return

    SW(7): ! Attribute  Change
          Check Draw
          change attribute (x, Y)
          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(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.
            Oric (4, Wx, Wy)
            Oric (5, Wx, y)
            Oric (5, x,y)
            Oric (5, x, Wy)
            Oric (5, Wx, wy)
            return

    SW(*):
    end

    end of file