! File NMOUSE:TERMP ! Terminal handler process (needs revamping) %option "-low-nons-nocheck-nodiag" %include "mouse.inc" ! Input is inserted by the interrupt handler into a type-ahead buffer ! belonging to this process, the interrupt handler deals with: ! ^S suspend output (XOFF) ! ^Q resume output (XON) ! ^O toggle discard mode ! ^P exempt next character from control significance ! ^X discard type-ahead ! ^^ reboot ! ^Y clobber last input client (needs tidying up) ! The main process deals with keyboard input request messages. On every ! request the entire contents of the type-ahead buffer are copied into ! the message buffer, which is returned to the user, a message size of ! 0 indicates that there was no type-ahead. This method is somewhat crude, ! in that it requires a message interchange for every call on TESTSYMBOL, ! so if input is being expected, messages will be flying around all the time. ! It works, but should be improved when time permits. ! Output is inserted into the buffer by routine SCREENPUT, ! and removed from the buffer by the interrupt handler. ! SCREENPUT is a nasty at-routine (16_3FA2) callable by any process. %constinteger input buffer size = 300 %constinteger output buffer size = 2000 %constinteger ion=16_B1,iof=16_91{,ion=iof %ownrecord (interrupt handler fm) ih %ownrecord (semaphore fm)%name output buffer full %ownrecord (mailbox fm)%name service mailbox, reply %ownrecord (message fm)%name request == nil %ownrecord (process fm)%name last customer == nil %ownbytearray input buffer(1:input buffer size) %ownbytearray output buffer(1:output buffer size) %ownbytename in start, in limit, in put, in get %ownbytename out start, out limit, out put, out get %owninteger breaking=0,discard=0,xoff=0,dleing=0 {@16_3724} %own {} %integer exemptmask {}=0 @16_3f9c - %integer ttygla,%byte ttyrows,ttycols,%short ttyjmp,%integer screenputad @16_4000c1 %byte acias,*,aciad %begin %label int %routine keyboard put(%register(d0)%integer sym) ! Add character to input buffer (called from interrupt handler) %register(a0)%bytename new *temp a1 input = sym new == input[1] new == instart %if new==inlimit {wrap round} input == new %unless new==inget {do not over-fill} %end %integerfn output pending ! Number of bytes waiting in output buffer %register(d1)%integer a *temp d0 a = addr(output)-addr(outget) a = a+output buffer size %if a<0 %result = a %end %routine screenput(%integer x) ! Add character to output buffer, wait if nearly full. { %bytename new { %integer olda4=a4 { a4=ttygla { %if discard=0 %start { output = x; new == output[1] { new == outstart %if new==outlimit { output == new { acias = ion { semaphorewait(output buffer full) %if outputpending>outputbuffersize-5 rompsym(x!128) { %finish { a4 = olda4 %end ttygla = a4 ttyrows = 24; ttycols = 80; ttyjmp = 16_4ef9 *lea screenput,a0; screenputad = a0 ih = 0 ih_pc = addr(int) add interrupt handler(5) become process(2000) exemptmask = 0 output buffer full == create semaphore("",0) service mailbox == create mailbox("Keyboard mailbox",create semaphore("",0)) in start == input buffer(1) in limit == in start [input buffer size] in put == in start in get == in start out start == output buffer(1) out limit == out start [output buffer size] out put == out start out get == out start acias = ion %cycle request == receivemessage(service mailbox) last customer == request_owner %while inget##input %cycle request_size = request_size+1 request_data(request_size) = inget inget == inget[1] inget == instart %if inget==inlimit %repeat send message(request,request_reply) discard = 0 %repeat int: *temp d0-d1/a0-a1 %register(d1)%integer sym sym = acias %if sym&16#0 %start {framing error => break} sym = aciad acias = ion breaking = 1 ! %elseif sym&4#0 {DCD (DTR) gone} ! sym = aciad ! acias = ion %elseif sym&1#0 {input ready} sym = aciad&127 %if breaking#0 %start breaking = 0 acias = ion %elseif dleing#0 dleing = 0 %elseif sym<32 {control character} %and 1<>2 - %and output buffer full_counter<0 %start int signal semaphore(output buffer full) %finish %finish %finish returnfrominterrupt *nop %end