; If the VMS terminal port driver does not set the TTY$M_PC_NOTIME ;bit in the terminal UCB field UCB$W_TT_PRTCTL then the VMS terminal ;class driver updates the field UCB$L_DUETIM to be the system-absolute ;time at which the sanity timer is due to expire. In general, if this ;time is in the future it means I/O is in progress, if in the past it ;is an indication of how long it has been since some I/O took place, and if ;it is zero it means the terminal doesn't keep track of the due time. ; ; Here is a code fragment to retrieve the idle time in seconds. The ;first argument is the address of a descriptor to the terminal name and ;the second an address of a longword to return the idle time in seconds to. ; ; Ken Adelman .entry idletime,^m<> pushal (ap) pushaw b^idletime_k calls #2,g^sys$cmkrnl ret .entry idletime_k,^m ifnord #8,@4(ap),accvio ; make sure we can read descriptor ifnowrt #4,@8(ap),accvio ; and write the return address jsb g^sch$iolockr ; lock I/O database for read ;; we are now at IPL 2 (ASTDEL) movl 4(ap),r1 ; search for device UCB jsb g^ioc$searchdev blbc r0,20$ ; not found tstl w^ucb$l_duetim(r1) bneq 9$ mnegl #1,@8(ap) brb 20$ 9$: subl3 w^ucb$l_duetim(r1),g^exe$gl_abstim,r1 bgeq 10$ clrl r1 10$: movl r1,@8(ap) 20$: pushl r0 jsb g^sch$iounlock setipl #0 popr #^M ret accvio: movzwl s^#ss$_accvio,r0 ret .end ; The following code is a hack which causes the terminal driver ;to update the DUETIM field for all terminals. You run this ONCE per boot ;and it patches the terminal driver on-the-fly: .Title Install-Idle-Monitor ; ; This loads code into system space and patches into the ; terminal port/class interface to update UCB$L_ABSTIM whenever ; a character is sent or received. This allows us to keep ; track of 'idletime' on non-TIMED devices. ; .library /SYS$LIBRARY:LIB/ $CXBDEF $DDTDEF $DPTDEF $DYNDEF $TTYUCBDEF $TTYVECDEF $UCBDEF .Entry Install_Idle_Monitor,^m<> $CMKRNL_S $$Install_Idle_Monitor Ret .Entry $$Install_Idle_Monitor,^m ; ; See if we have an RTA0 device installed. ; Clrl R7 ; Assume no RTDRIVER DDT to patch Jsb G^Sch$IOLockR ; Lock the I/O database MovAQ RT_DEVICE,R1 Jsb G^IOC$SearchDev ; Search for RTA0 Blbc R0,1$ Movl UCB$L_DDT(R1),R7 1$: ; ; Allocate a buffer to hold the code the be loaded into ; nonpaged pool ; MovL #CodeLen+12,R1 ; Skip 12 bytes for pool header TstL R7 BEql 2$ AddW2 DDT$W_FDTSIZE(R7),R1 ; Room for old FDT AddW2 #3*4,R1 ; Room for the new FDT entry 2$: Jsb G^Exe$AllocBuf Blbs R0,10$ Pushl R0 Brb Done 10$: ; ; Copy the code into the pool ; MovAB 12(R2),R6 ; Address of start of code MovC3 #CodeLen,W^Code,(R6) ; Copy code into pool ; ; Link the code into the class interface to TTDRIVER. ; MovL G^TTY$GL_DPT,R1 ; Get TTDRIVER DPT MovZWL DPT$W_VECTOR(R1),R0 ; Offset to CLASS VECTOR AddL2 R0,R1 ; Address of CLASS VECTOR MovL CLASS_GETNXT(R1),B^V1_Jump-Code(R6) MovL CLASS_PUTNXT(R1),B^V2_Jump-Code(R6) MovAB B^V1-Code(R6),CLASS_GETNXT(R1) MovAB B^V2-Code(R6),CLASS_PUTNXT(R1) ; ; Build a new FDT routine for RTTDRIVER. ; Tstl R7 Beql 20$ Addl3 S^#Patched_RT_FDT-Code,R6,R0; Pointer to start of new FDT Movl DDT$L_FDT(R7),R1 ; Pointer to start of old FDT MovQ (R1)+,(R0)+ ; Copy the supported I/O mask MovQ (R1)+,(R0)+ ; Copy the buffered I/O mask MovQ -16(R1),(R0)+ ; Copy the supported into the new entry MovAB B^RTT_Fix-Code(R6),(R0)+ ; New FDT code address MovZWL DDT$W_FDTSIZE(R7),R2 SubL2 #16,R2 ; Calculate size of remaining FDT MovC3 R2,(R1),(R0) ; Move it MovAL B^Patched_RT_FDT-Code(R6),DDT$L_FDT(R7) AddW2 #12,DDT$W_FDTSIZE(R7) ; Update the pointers to the new FDT 20$: ; ; Exit ; Pushl #SS$_NORMAL Done: Movl G^CTL$GL_PCB,R4 Jsb G^SCH$IoUnLock PopL R0 Ret RT_DEVICE: .Ascid /_RTA0:/ ; ; This code sits in between the port/class interface for each ; terminal and updates the "DUETIM" field when each I/O occurs ; It *Must* be PIC. ; Code: V1: BBC #TTY$V_PC_NOTIME,UCB$W_TT_PRTCTL(R5),10$ MovL @#EXE$GL_ABSTIM,UCB$L_DUETIM(R5) 10$: Jmp @I^#00000000 V1_Jump = .-4 V2: BBC #TTY$V_PC_NOTIME,UCB$W_TT_PRTCTL(R5),10$ MovL @#EXE$GL_ABSTIM,UCB$L_DUETIM(R5) 10$: Jmp @I^#00000000 V2_Jump = .-4 Rtt_Fix:MovL @#EXE$GL_ABSTIM,UCB$L_DUETIM(R5) Rsb CodeLen = .-Code Patched_RT_FDT: .End Install_Idle_Monitor