.title keypad .ident /15aug/ .mcall dir$, qiow$, ttsym$ ttsym$ ttlun = 5 tiflg = 1 esc = 33 ; if they press keypad key when buffer at 79 or 80 ; then ESC will not be seen or invalid sequence is seen. ; Hence they can only press 78 non-keypad keys before pressing keypad key. ; - NO ONE could be that silly ? bufsiz = 80. .psect user$d,d tt: qiow$ IO.RNE,ttlun,tiflg,,iostat,, buff: .blkb bufsiz iostat: .blkw 2 ; iostat area escp: .byte TC.ESQ,1 ; SF.SMC esqseq escsiz = . - escp ttyp: .byte TC.TTP,0 ; terminal type ttysiz = . - ttyp ; table of valid terminal types - do vt2?? exist in software yet ? termt: .byte T.V100, T.V101, T.V102, T.V105, T.V125, T.V131, T.V132 .byte 0 ; terminator ; N.B. same as T.UNKO .even .macro key ascii,number .ascii /ascii/ .endm ; table to map 3rd chr from keypad sequence to a number. table: key p,0 ; 0 key q,1 ; 1 key r,2 ; 2 key s,3 ; 3 key t,4 ; 4 key u,5 ; 5 key v,6 ; 6 key w,7 ; 7 key x,8. ; 8 key y,9. ; 9 key P,10. ; PF1 key Q,11. ; PF2 key R,12. ; PF3 key S,13. ; PF4 key m,14. ; - key l,15. ; , key M,16. ; Enter key n,17. ; . .byte 0 ; terminator .even ; ; keypad returns a digit indicating which key has been pressed on ; keypad. ; NB has been put into alternate keypad mode previously. ; .psect user$i keypad:: tst (r5)+ ; discard nargs mov #tt,r0 ; assume unfiddled with 10$: dir$ r0 ; and do it cmpb #IE.EOF,iostat ; ^Z ? bne 20$ ; br, if no mov #-1,@(r5)+ ; return -1 return ; easy way - seems too difficult to check is.suc, is.esc, is.cr etc... ; 20$: mov #buff,r1 ; escape in buffer ? mov #bufsiz,r2 30$: cmpb (r1)+,#esc ; esc ?? beq 40$ ; br, if yes sob r2,30$ ; else no escape in buffer br 10$ ; and start again 40$: cmpb (r1)+,#'O ; next character must be O bne 10$ ; and start again movb (r1)+,r2 ; 3rd chr => r2 mov #table,r1 ; check valid 3rd chr 50$: tstb @r1 ; end of table ? beq 10$ ; and start again cmpb (r1)+,r2 ; valid ?? beq 60$ ; br, if yes inc r1 ; skip over number br 50$ 60$: movb @r1,@(r5)+ ; and return key no return ; zero the buffer after a read, successful or otherwise clrbuf: mov #buff,r3 mov #bufsiz,r4 10$: clrb (r3)+ sob r4,10$ return ; ; attach terminal for duration of CALC and set ESQSEQ ; ttatt:: tst (r5)+ ; discard nargs mov #tt,r0 ; attach tt mov #IO.GTS,Q.IOFN(r0) ; see what we got .... mov #buff,q.iopl(r0) ; use buff for return mov #8.,q.iopl+2(r0) ; and size 8. bytes dir$ r0 ; do it.... bcc 10$ ; br, if no error cmpb #IE.IFC,iostat ; IO.GTS not sysgened ?? bne 60$ ; br, if ne, don't know it mov #-1,r1 ; -1 = GTS not SYSGENED br 70$ ; SF.GMC/SMC supported ?? 10$: bit #f2.sch,buff+2 ; SF.SMC supported ? beq 20$ ; br, if no bit #f2.gch,buff+2 ; SF.GMC supported ? bne 30$ ; br, if yes 20$: mov #-2,r1 ; -2 = SF.GMC/SMC not SYSGENED br 70$ ; vt100 like terminal ? 30$: mov #SF.GMC,Q.IOFN(r0) mov #ttyp,Q.IOPL(r0) ; address mov #ttysiz,Q.IOPL+2(r0) ; size dir$ r0 ; do it movb ttyp+1,r1 ; put terminal type in register mov #termt,r2 ; get pointer to valid terminals 40$: tstb @r2 ; end of table ?? bne 50$ ; br, if no mov #-3,r1 ; -3 = not VT100 type terminal br 70$ 50$: cmpb (r2)+,r1 ; is this our terminal ?? bne 40$ ; br, if not this one mov #IO.ATT!TF.ESQ,Q.IOFN(r0) ; PHEW !!, he cried dir$ r0 ; finally DO IT.... bcc 80$ 60$: mov #-4,r1 ; -4 = unknown error 70$: mov r1,@(r5)+ ; set error flag mov #IO.RNE,Q.IOFN(r0) ; function Read No Echo mov #buff,q.iopl(r0) ; buffer address mov #bufsiz,q.iopl+2(r0) ; buffer length return 80$: mov #SF.GMC,Q.IOFN(r0) ; see if set /escseq set mov #escp,Q.IOPL(r0) ; address mov #escsiz,Q.IOPL+2(r0) ; size dir$ r0 ; do it.... bcs 60$ ; error movb escp+1,r1 ; save what ever it was movb #1,escp+1 ; make function SET /ESCSEQ mov #SF.SMC,Q.IOFN(r0) ; set /escseq dir$ r0 ; do it.... bcs 60$ ; error movb r1,escp+1 ; set up their default clr r1 ; clear error flag br 70$ ; restore default ; ; detach terminal CALC and set ESQSEQ ; ttdet:: tst (r5)+ ; discard nargs clr @(r5) ; clear error flag mov #tt,r0 ; attach tt mov #IO.DET,Q.IOFN(r0) dir$ r0 bcc 30$ 10$: mov #-1,@(r5)+ ; set error flag 20$: mov #IO.RNE,Q.IOFN(r0) ; function Read No Echo mov #buff,q.iopl(r0) ; buffer address mov #bufsiz,q.iopl+2(r0) ; buffer length return 30$: ; escp+1 already set up ; with user default mov #SF.SMC,Q.IOFN(r0) mov #escp,Q.IOPL(r0) ; address mov #escsiz,Q.IOPL+2(r0) ; size dir$ r0 ; do it.... bcs 10$ br 20$ .end