! File NMOUSE:IO_T ! TERMINAL device interface module %option "-low-nons-nocheck-nodiag" %include "mouse.inc" ! We do not deal with ^S/^Q/^O/^T/^Y, the terminal process does that. ! Page mode, however, IS dealt with here, but is disabled by default. %constinteger noecho=1,notermecho=2,nobuffering=4,nopage=8 %owninteger normal=nopage,mode=nopage %ownrecord(mailbox fm)%name server == nil, reply == nil %ownrecord(message fm)%name msg == nil %owninteger msgpos = 0, linesleft = maxint %constinteger del=127,bs=8,tab=9,lf=10,cr=13,esc=27 @16_4000c1 %byte acias,*,aciad {@16_3724} %own%integer exemptmask {@16_3fa0} %own%byte ttyrows {@16_3fa2} %routine screenput(%integer x) %cycle; %repeatuntil acias&2#0 aciad = x %cycle; %repeatuntil acias&2#0 %end %externalintegerfn testsymbol %if msg==nil %start %if server==nil %start server == lookup mailbox("Keyboard mailbox") %signal 3,3,,"Keyboard mailbox not found" %if server==nil reply == create mailbox("",create semaphore("",0)) %finish msg == acquire message buffer msg_reply == reply; msg_size = 0 send message(msg,server) msg == receive message(reply) msgpos = 0 %finish %if msgpos>=msg_size %start return message buffer(msg); msg == nil; %result = -1 %finish msgpos = msgpos+1 %result = msg_data(msgpos) %end %externalintegerfn pendsymbol %integer k = testsymbol msgpos = msgpos-1 %unless k<0 %result = k %end %integerfn getsym %integer k k = testsymbol %until k>=0 %result = k&127 %end %routine putstring(%string(255)s) %integer i screenput(charno(s,i)) %for i = 1,1,length(s) %end %routine refresh input (%record(fcbfm)%name cb) %owninteger pendeof=0 %integer k %routine add(%integer k) byte(cb_l) = k; cb_l = cb_l+1 %end pendeof = 0 %and %signal 9,,,"End of file" %unless pendeof=0 k = pendsymbol linesleft = ttyrows-1 %if mode&nopage=0 putstring(cb_prompt) %unless cb_prompt==nil cb_p = cb_bs; cb_l = cb_p %cycle k = getsym %if k<' ' %and 1<='@' k = getsym %repeat %exit %finish %if k='F'-64 %start normal = normal!!nopage mode = (mode&\nopage)!(normal&nopage) %if mode&nopage#0 %start linesleft = maxint screenput(' ';bs) %else linesleft = ttyrows-1 screenput('P';bs) %finish %continue %finish %if mode&nobuffering#0 %start k = getsym %if k='P'-64 add(k); %exit %finish %if k='D'-64 %or k='Z'-64 %start pendeof = 1; %exit %finish %if k=cr %or k=lf %start add(k); screenput(cr;lf) %if mode¬ermecho=0; %exit %finish %if k=del %start %if cb_l>cb_bs %start cb_l = cb_l-1; screenput(bs;' ';bs) %if mode&noecho=0 %finish %elseif k=bs %or k='X'-64 %while cb_l>cb_bs %cycle screenput(bs;' ';bs) %if mode&noecho=0; cb_l = cb_l-1 %repeat %elseif k>=' ' add(k); screenput(k) %if mode&noecho=0 %elseif k='P'-64 add(getsym) %elseif k=tab add(' ';' ';' ') %else %exitif k='C'-64 screenput('?';'^';k+64;'?';bs;bs;bs;bs) %finish %repeatuntil cb_l>=cb_bl-10 {in case longish esc seq} %end %routine newline %integer k screenput(cr;lf) linesleft = linesleft-1 %if linesleft<=0 %start %if mode&nopage#0 %start linesleft = maxint %else putstring("^F:Free LF:Line Other:Page"); screenput(cr) k = testsymbol %until k>=0 %if k='F'-64 %start mode = mode!!nopage; normal = mode linesleft = maxint %elseif k=lf linesleft = 1 %else linesleft = ttyrows-1 %finish putstring(" "); screenput(cr) %finish %finish %end %routine flush output (%record(fcbfm)%name cb,%integer k) %unless k<0 %start %if k=nl %then newline %else screenput(k) %finish cb_p = cb_bs; cb_l = cb_bs %end %routine read input(%record(fcbfm)%name cb,%integer amount,%bytename p) ! (POSITION ignored) %while amount>0 %cycle amount = amount-1 refresh input(cb) %if cb_p>=cb_l p = byte(cb_p); cb_p = cb_p+1; p == p[1] %repeat %end %routine write output(%integer amount,%bytename p) %while amount>0 %cycle amount = amount-1 %if p=nl %then newline %else screenput(p) p == p[1] %repeat %end %externalintegerfn terminalmode %result = mode %end %externalroutine set terminalmode(%integer x) x = normal %if x<0 mode = x %if mode&nopage#0 %start linesleft = maxint %else linesleft = ttyrows-1 %finish %end %externalrecord(fcbfm)%map FOP %alias "FOP_T" - (%integer code,%string(*)%name file,%name x) %record(fcbfm)%name cb == nil %integer pc,fastpc %routine cbop (%record(fcb fm)%name cb,%integer code,p1,p2,%bytename b) %switch sw(cbopclose:cbopread) ->sw(code) %if cbopclose<=code<=cbopread %signal 3,4,code,"Illegal fcb operation (:T)" sw(cbopflush): flushoutput(cb,p1); %return sw(cbopwrite): readinput(cb,p2,b); %return sw(cboprefresh): refreshinput(cb); %return sw(cbopread): writeoutput(p2,b); %return sw(cbopclose): sw(cbopabort): heapput(cb_bs) %unless cb_bs=0; cb_bs = 0 dispose(cb_prompt) %unless cb_prompt==nil; cb_prompt == nil dispose(cb) %end *lea cbop,a0; *move.l a0,pc %if code = fop openi %start *lea refreshinput,a0; *move.l a0,fastpc cb == newfcb(file) cb_fastpc = fastpc; cb_pc = pc; cb_gla = a4 cb_prompt == string(heapget(256)) cb_prompt = ":" cb_bs = heapget(256) cb_bl = cb_bs+256 cb_fs = cb_bs; cb_fl = cb_fs cb_p = cb_bs; cb_l = cb_p %elseif fop openo <= code <= fop opena *lea flushoutput,a0; *move.l a0,fastpc cb == newfcb(file) cb_fastpc = fastpc; cb_pc = pc; cb_gla = a4 %else %signal 3,3,code,"File operation not supported (:T)" %finish %result == cb %end