! Qsart process Interrupt Driven 
! AJS Dec 87 {for old Mouse}
!This version has the X-On, X-Off code commented out ( !flow! ) JHB 3/11/88

%option "-low-nocheck-nodiag-noline-nostack"
%include "moose:mouse.inc"

! Physical stuff
%constant %integer boardaddr = 16_7FFC0    ;! Change as appropriate

%recordformat DEVICE FM(%byte bstatus,data,intvec,dstatus,x,mode,y,command)
@boardaddr %record(device fm) dev

%constant %integer mode1=16_4e,mode2=16_30,comm=16_37
%constant %integer txie=1,rxie=2,reset=8
%Constinteger rion=2, tion=3 ,tioff=rion

%Routine Start device
    dev_bstatus = reset;   
    dev_bstatus = 0;       
    dev_mode = mode1;      
    dev_mode = mode2+13; 
    dev_dstatus = 0
    dev_dstatus = 0
    dev_dstatus = 0
    dev_command = comm;    
%End

%Constinteger kbbs = 512-1
%Recordformat kb buff fm(%Integer sem,bs,be,in,out,notempty,
                         %Bytearray buff(0:kbbs),%integer op)

%Constinteger opbs = 1024-1
%Constinteger thresh = opbs//2 {original}
%Recordformat op buff fm(%Integer notfull,bs,in,out,
                         %bytearray buff(0:opbs),%integer code,ctrlo,
                         %Integer xonsem, %integer xonflag, %integer gotsem)

%ownrecord(interrupt handler fm) ih
%ownrecord(kbbufffm)%name        kb buff
%Ownrecord(opbufffm)%name        op buff
%Ownrecord(mailboxfm)            mbox
%Ownrecord(semaphorefm)          sem
%ownrecord(semaphorefm)          notfull
%Ownrecord(semaphorefm)          notempty
%ownrecord(semaphorefm)          xonsem
%Ownrecord(semaphorefm)          inmutex,outmutex

%Routine Initialise
   %Label x,y,l,done,nw,rej,nott,noto,notq,nots,rint,nwrp,endt,noty
   %Label tint,dcdint,nosig,notx
   %Integer t
   @0(a6)%Record(interrupthandlerfm) nih
   @0(a4)%Record(kbbufffm) kb
   @0(a0)%Record(opbufffm) op

   kbbuff == new(kbbuff); kbbuff=0
{   putstring("Kb buff @");putlong(addr(kbbuff));putsym(10)
   kbbuff_sem = addr(sem)
   kbbuff_bs = addr(kbbuff_buff(0))
   kbbuff_be = addr(kbbuff_buff(kbbs))+1
   kbbuff_in = kbbuff_bs
   kbbuff_out = kbbuff_bs
   kbbuff_op = addr(opbuff)
   kbbuff_notempty = addr(notempty)

   setup interrupt handler (ih, addr(x))
   ih_a4 = addr(kbbuff)
   add interrupt handler (ih,5)
   dev_bstatus = rion
   %Return

x:
   *move.b dev_bstatus, d0
   *btst #7,d0
   *beq  done

   *move.b dev_dstatus, d0
   *btst #1,d0
   *bne  rint

   *btst #0,d0
   *bne tint

done:
   return from interrupt

tint:
   *move.l kb_op,a0
   *move.l op_out,d0
   *cmp.l op_in,d0
   *beq endt
   *and.l  #opbs,d0
   *move.l op_bs,a1
   *move.b 0(a1,d0),dev_data
   *addq.l #1,op_out
   *move.l op_in, a1
   *sub.l  op_out, a1
   *cmp.l #thresh, a1
   *bne nosig
   int signal semaphore (record(op_notfull))
nosig:
   *bra done
endt:
   *move.b #tioff, dev_bstatus
   *bra done

rint:
   *move.b dev_data,d0

!flow!    *cmp.b #19,d0     ;! Control S
!flow!    *bne nots
!flow!    *move.l kb_op,a0
!flow!    op_xonflag = 1
!flow!    dev_bstatus = tioff
!flow!    *bra done
nots:
!flow!    *cmp.b #17,d0     ;! Control Q
!flow!    *bne notq
!flow!    *move.l kb_op, a0
!flow!    %if op_xonflag = 1 %start
!flow!       op_xonflag=0
!flow!       dev_bstatus = tion
!flow!       int signal semaphore (record(op_xonsem))
!flow!    %Finish
!flow!    *bra done      
notq:
   *move.l kb_in,a0
   *move.b d0,(a0)+
   *Cmp.l  kb_be,a0
   *Bne nw
   *move.l kb_bs,a0
nw:
   *Cmp.l  kb_out,a0
   *Beq rej
   *Move.l a0,kb_in
   int signal semaphore (record(kb_notempty))   ;! Should only do when going
                                                ;! notempty
   *bra done
rej:
   *move.b #7,d0
   *jsr 16_41c
   *bra done
%End

%Begin
   %Integer k,t, waiting=0,sym,i,diff
   %record(Dictfm)%name m

   %on 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 %start
      PutString("QFart process failed -")
      putlong(event_event);putsym(' ');putstring(event_message)
      putsym(10)
      %Stop
   %Finish

   putstring("QFart process - 12/5/88");putsym(10)

{}   start device
   setup semaphore (sem)
   setup semaphore (notfull)
   setup semaphore (inmutex)
   setup semaphore (outmutex)
   setup semaphore (xonsem)
   setup semaphore (notempty)

   opbuff == new(opbuff)
   opbuff = 0
   opbuff_bs = addr(opbuff_buff(0))
   opbuff_in = 0
   opbuff_out= 0
   opbuff_notfull = addr(notfull)
   opbuff_xonsem = addr(xonsem)
   opbuff_xonflag = 0
   opbuff_ctrlo = 0
   Initialise
   m == poa_logdict
   m == m_alt %while m_alt ## NIL

   i = make entry("Q_MUTEX_IN", m)
   %Signal 3,0,0, "Failed to enter Q_MUTEX_IN" %if i = 0
   integer (i) = addr(inmutex)
   
   i = make entry("Q_MUTEX_OUT", m)
   %Signal 3,0,0, "Failed to enter Q_MUTEX_OUT" %if i = 0
   integer (i) = addr(outmutex)

   i = make entry("Q_OP_BUFFER",m)
   %signal 3,0,0, "Failed to enter Q_OP_BUFFER" %if i = 0
   integer (i) = addr(opbuff)

   i = make entry("Q_KB_BUFFER",m)
   %signal 3,0,0, "Failed to enter Q_KB_BUFFER" %if i = 0
   integer (i) = addr(kbbuff)

   signal semaphore (inmutex)
   signal semaphore (outmutex)

{}   putstring("Qfart ready");putsym(nl)

   Semaphore Wait (sem)

   Putstring("QFart has fallen through it's end");putsym(nl)
%End
