! 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,nw,rej,nott,noto,notq,nots,rint,nwrp,endt,noty
Label tint,dcdint,nosig,notx, done
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 #2,d0; ! DCD
*bne dcdint
*btst #5,d0; ! OVRN
*bne dcdint
*btst #4,d0; ! FE
*bne dcdint
*btst #0,d0; ! RDRF
*bne rint
*btst #1,d0; ! TDRE
*bne tint
done:
return from interrupt
dcdint:
! Read the data register to clear the condition
! (throw the character away, as it's rubbish)
*move.b acia d, d0
! Now, in case there's been a TX interrupt while we were
! unplugged, we have to test the TX data register status....
*btst.b #1, acia s; ! TDRE
*beq 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:
-> done
endt:
*move.b #16_91,acias; ! RX int on, TX int off, 8+2
-> 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; ! TX int off to zap output
op_out = op_in
int signal semaphore (record(op_notfull))
finish
-> done
noto:
*cmp.b #19,d0 ;! Control S
*bne nots
*move.l kb_op,a0
op_xonflag = 1
acias = 16_91; ! TX int off to freeze output
-> 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; ! TX int on (& RX int, 8+2)
int signal semaphore (record(op_xonsem))
Finish
-> done
notq:
*cmp.b #24,d0 ;! Control X
*bne notx
kb_in = kb_out
! -> 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
-> done
rej:
*move.b #7,d0
*jsr 16_41c; !????
-> 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 - 13/4/88");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