! Local Processor 6850 ACIA Terminal Process (interrupt driven) - NEW

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

%Recordformat clockreqfm (%record(messagefm) msg,
                          %Integer ms)

! Physical stuff
@16_4000c0 %byte *,acia s,*,acia d

%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
%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
%Ownrecord(clockreqfm)           clockreq
%Ownrecord(mailboxfm)%name       clockmbx
%Ownrecord(mailboxfm)            inclock

%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)
   acias = 16_91  ;! Enable interrupts
   %Return

x: *move.b acia s, d0

   *btst #0,d0
   *bne rint

   *Btst #1,d0
   *bne tint

   *btst #4,d0
   *bne dcdint
   
   *btst #5,d0
   *bne dcdint

done:
   return from interrupt

dcdint:
   *move.b acia d, d0
   *bra done

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),aciad
   *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 #16_91,acias
   *bra done

rint:
   *move.b acia d,d0
   *and.b #127,d0

   *cmp.b #30,d0     ;! Control T {now CTRL-^ actually !}
   *bne nott
   *reset
   *mtsr #16_2700
   *move.l 0,sp
   *move.l 4,-(sp)
   *rts
nott:
   *cmp.b #15,d0     ;! Control O
   *bne noto
   *move.l kb_op, a0
   op_ctrlo = op_ctrlo!!1
   %if op_ctrlo = 1 %start
      acias = 16_91
      op_out = op_in
      int signal semaphore (record(op_notfull))
   %finish
   *bra done
noto:
   *cmp.b #19,d0     ;! Control S
   *bne nots
   *move.l kb_op,a0
   op_xonflag = 1
   acias = 16_91
   *bra done
nots:
   *cmp.b #17,d0     ;! Control Q
   *bne notq
   *move.l kb_op, a0
   %if op_xonflag = 1 %start
      op_xonflag=0
      acias = 16_B1
      int signal semaphore (record(op_xonsem))
   %Finish
   *bra done      
notq:
   *cmp.b #24,d0    ;! Control X 
   *bne notx
   kb_in = kb_out
!   *bra done
notx:
   *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

%Routine fire timer
{   putstring("Fire timer")
   clockreq_ms = realtime + 10000
   send message (clockreq,clockmbx,inclock)
%End

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

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

   putstring("Local Terminal process - 18/3/87");putsym(10)

   setup semaphore (sem)
   setup semaphore (notfull)
   setup semaphore (inmutex)
   setup semaphore (outmutex)
   setup semaphore (xonsem)
   setup semaphore (notempty)
   setup mailbox (inclock,sem)
   setup message (clockreq,sizeof(clockreq))

   i = Find Entry ("CLOCK_REQ",poa_logdict)
   %Signal 3,0,0,"Failed to find CLOCK_REQ" %if i = 0
   clockmbx == record(integer(i))

   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("T_MUTEX_IN", m)
   %Signal 3,0,0, "Failed to enter T_MUTEX_IN" %if i = 0
   integer (i) = addr(inmutex)
   
   i = make entry("T_MUTEX_OUT", m)
   %Signal 3,0,0, "Failed to enter T_MUTEX_OUT" %if i = 0
   integer (i) = addr(outmutex)

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

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

   signal semaphore (inmutex)
   signal semaphore (outmutex)

   fire timer
   %Cycle
      Semaphore Wait (sem)
      clockrep == dequeue(inclock_queue)
      %if clockrep ## NIL %start
         %if opbuff_gotsem = 1 %start
            %if outmutex_count < 0 %start
               {PutString("*Grab*")
               opbuff_gotsem = 0
               signal semaphore (outmutex)
            %finish
         %finish
         fire timer
      %Finish
   %Repeat
%End
