! File MOUSE:TERMP ! Terminal handler process ! 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 ! ^T reboot if followed by R ! ^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. %option "-low-nons-nocheck-nodiag" %include "mouse.inc" %constinteger input buffer size = 300 %constinteger output buffer size = 2000 %constinteger ion=16_B1,iof=16_91 %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 (pcb 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 %integer exemptmask @16_3f94 %integer ttygla @16_3fa0 %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 %finish a4 = olda4 %end %routine setup interrupts(%integer pc) %integer x ih = 0 ih_pc = pc x = or to sr(16_2000) add interrupt handler(5) x = move to sr(x) %end become process(2000) ttygla = a4 exemptmask = 0 output buffer full == create semaphore(0) service mailbox == create mailbox(create semaphore(0)) define kernel object(service mailbox,"Keyboard mailbox") 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 setup interrupts(addr(int)) ttyrows = 24; ttycols = 80; ttyjmp = 16_4ef9 *lea screenput,a0; screenputad = a0 acias = ion %cycle request == receivemessage(service mailbox) last customer == request_sender reply == request_reply request_size = 0 %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