.title ttio - a keyboard capture package ;++ ; ; Rev 1.1 ; ; Functions: ; ; TTINIT - initialize terminal for ttio ; TTRDY - return 1 if key has been pressed ; TTREAD - read 1 character from keyboard buffer. If empty, wait. ; TTFLSH - flush keyboard buffer ; MONITR - terminate task and restore characteristics ; TTREST - restore terminal characteristics ; TTWRT - write buffer to terminal ; ;-- .mcall qiow$s,qio$s,stop$s,setf$s,clef$s,wtse$s,astx$s .mcall ttsym$, alun$s .macro savreg jsr r5,$savr1 .endm savreg .psect c$data,d,rw bufsiz == 127. ; Buffer size kbsiz:: .word 0 ; Characters entered kbbuf:: .blkb bufsiz ; Keyboard buffer .even buf1:: .word 0 ttsym$ smctbl:: ; .byte tc.bin,1 ; Read-pass-all .byte tc.pth,1 ; Passthru .byte tc.nec,1 ; No echo .byte tc.smr,1 ; Lower .byte tc.8bc,1 ; EBC .byte tc.acr,0 ; Nowrap .byte tc.fdx,1 ; Full duplex .byte tc.hld,0 ; No hold .byte tc.tsy,1 ; Process XON/XOFF .byte tc.cts,0 ; Cancel ^S... tab1siz == . - smctbl exitbl: ; .byte tc.bin,0 .byte tc.pth,0 .byte tc.nec,0 .byte tc.smr,0 .byte tc.8bc,0 .byte tc.acr,0 .byte tc.fdx,0 ; Full duplex .byte tc.hld,0 ; No hold .byte tc.tsy,0 ; Process XON/XOFF ani: .byte tc.ani,0 scp: .byte tc.scp,0 tab2siz == . - exitbl .even extxt:: .ascii <15><12>/>/ exsiz == . - extxt .even .psect c$code,i,ro ; ; Initialize ; ttinit::savreg ; Save registers ini2: qiow$s #sf.gmc,#5,,,,,<#exitbl,#tab2siz> ; Get old characteristics qiow$s #sf.smc,#5,,,,,<#smctbl,#tab1siz> ; Set terminal to binary qiow$s #io.ata,#5,#1,,,,<#fixast> br tfl2 ; ...and flush ; ; Flush buffer ; ttflsh::savreg ; Save registers tfl2: clr kbsiz ; Flush string clef$s #5. ; Mark empty return ; ; Restore buffer and terminate (STOP) task. ; monitr::savreg ; Save registers call ttres2 ; Restore terminal qiow$s #io.wvb,#5,#2,,,,<#extxt,#exsiz,#0> ; Write prompt stop$s ; Stop task jmp ini2 ; Initiate terminal ; ; Restore terminal characteristics ; ttrest::savreg ; Save registers ttres2: qio$s #sf.smc,#5,,,,,<#exitbl,#tab2siz> ; Restore terminal qiow$s #io.det,#5,#2,,,,<> return ; ; Read character, EF 8 used for flagging ; ttread::savreg ; Save registers tstb kbsiz ; Any character entered? bne retch ; Yes, return it wtse$s #5. ; No, wait until it becomes retch: mov #kbbuf,r1 ; Get pointer to buffer. mov r1,r2 ; Copy pointer. clr r0 ; Get character. bisb (r2)+,r0 dec kbsiz ; Get length of buffer. beq 2$ ; Done... mov kbsiz,r3 1$: movb (r2)+,(r1)+ ; Copy down buffer. sob r3,1$ 2$: clef$s #5 ; Clear flag. return ; ; Return 0 if buffer empty, otherwise 1 ; ttrdy:: savreg ; Save registers clr r0 ; Clear flag tst kbsiz ; Anything there yet? beq 1$ ; Nope inc r0 ; Yes, change into a 1 1$: return ; ; Put character to terminal ; ; ttwrt(buffer,length) ; char *buffer; ; int length; ; ttwrt:: mov 2(sp), r2 ; Buffer location mov 4(sp), r3 ; Buffer size qiow$s #io.wvb,#5,#2,,,, ; Go write it ; qio$s #io.wvb,#5,,,,, ; Go write it return ; Restore registers and exit ; ; Two checks... ; isansi:: clr r0 tstb ani+1 beq 10$ inc r0 10$: return ; isscope:: clr r0 tstb scp+1 beq 10$ inc r0 10$: return ; ; AST service entry ; fixast: mov r0,-(sp) ; Save register mov kbsiz,r0 ; Size movb 2(sp),kbbuf(r0) ; Copy character inc kbsiz ; Bump length. mov (sp)+,r0 tst (sp)+ ; Pop off character setf$s #5. ; Flag for character entered astx$s ; ...and return control ; ; Routine for saving registers ; $savr1: mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) mov r1,-(sp) mov #1$,-(sp) jmp (r5) 1$: mov (sp)+,r1 mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r4 mov (sp)+,r5 rts pc .end