	.Title	TERM_Info - Get information about a terminal
	.Ident	/V01.001/
	.Enable	SUP                                 
	.Default Displacement,Word
	.Subtitle Introduction
;+
;
; ----- TERM_Info:  Get information about a terminal;
;
; Facility:
;
;	VAX/VMS system programming
;
; Abstract:
;
;	This module provides a routine which can be called from any
;	VAX native  language to obtain information about a specific
;	terminal.
;
; Environment:
;
;	VAX/VMS native mode, VMS V4.2 or later, CMKRNL privilege.
;
; Version:	V01.001
; Date:		12-Apr-1988
;
;
; Modifications:
;
;
;-

	.Page
	.Subtitle Local definitions

	.Library "SYS$LIBRARY:LIB"
		;Get special macros from here
	.Link	"SYS$SYSTEM:SYS.STB"/Selective_Search
		;Ease the link process a bit

	.NoCross	;Save a tree

	$DCDEF				;Device class & type definitions
	$DDBDEF				;Device data block offsets
	$SSDEF				;System service codes
	$TTYUCBDEF			;Terminal UCB offsets
	$UCBDEF				;UCB offsets

	.Cross				;Turn CREF back on


	.Page
	.Subtitle	TERMINFO	- Get information about a terminal

;+
;
; ----- TERM_INFO:  Get information about a terminal
;
;
; The calling program must have  CMKRNL privilege and  must be linked
; with SYS.STB.
;
; Call sequence:
;
;  status.wlv = TERM_INFO (terminal.rt.dx, term_info_structure.m?.r)
;  term_info_structure :
;	.long	ucb$l_duetim
;	.long	ucb$l_pid
;	.word	ucb$w_wrtt_link
INFO_SIZE = 10
;
; Inputs:
;
;	4(AP)	- Address of a descriptor of the device name.
;
; Outputs:
;
;	8(AP)	- Address of a term_info structure.
;
;	R0	- SS$_NOPRIV:	 No CMKRNL privilege.
;		- SS$_ACCVIO:	 One of the arguments is not accessible.
;		- SS$_NOSUCHDEV: The specified device can't be found.
;		- SS$_IVDEVNAM:	 The specified device isn't a terminal.
;		- SS$_NORMAL:	 Success.
;
;-

	.Psect	TERM_INFO	EXE,RD,NOWRT,PIC,SHR,PAGE

	.Entry	TERM_INFO,^M<>		; Entry here

	$CMKRNL_S ROUTIN=B^20$,-	; Do this
		ARGLST=(AP)		;   in kernel mode

10$:	RET				; Done, status in R0

; Here in kernel mode to do all of the actual work.

20$:	.Word	^M<R2,R3,R4,R5,R6,R7,R8,R9,R10,R11>
		;Here in kernel mode to get some info

; First, check to see if we can read the argument list.

	MOVL	#SS$_ACCVIO,R0		; Presume we can't
	IFNORD	#<3*4>,(AP),10$		; Probe the argument list

; Check the number of arguments

	MOVL	#SS$_INSFARG,R0		; Presume we have too few arguments
	CMPB	#2,(AP)			; Do we have enough arguments?
	BNEQ	10$			; If NEQ no, it's wrong somehow
	
; Check to see if we can write the term_info structure.
	
	MOVL	#SS$_ACCVIO,R0		; Presume we can't
	IFNOWRT	#INFO_SIZE,@8(AP),10$	; Probe the term_info structure
	MOVL	8(AP),R10		; save the address of term_info struct.

; See if we can read the device name descriptor.

	MOVL	4(AP),R1		; Address the device name descriptor
	JSB	G^EXE$PROBER_DSC	; Probe the descriptor
	BLBC	R0,10$			; Sigh.
	MOVQ	R1,-(SP)		; Save copy of the probed descriptor
	MOVL	SP,R11			; Remember where it is
	CLRW	2(R11)			; Never mind the type and class info

; Ok.  Now go hunt down the device the user told us was a terminal

	MOVL	G^CTL$GL_PCB,R4		; Get my PCB address
	JSB	G^SCH$IOLOCKR		; Lock the I/O database mutex
	MOVL	R11,R1			; Address the device name descriptor
	JSB	G^IOC$SEARCHDEV		; Go search for the device.
	BLBC	R0,30$			; We lose.

; Now check to see if it's really a terminal.
	MOVL	#SS$_IVDEVNAM,R0	; Presume it isn't a terminal
       	CMPB	#DC$_TERM,UCB$B_DEVCLASS(R1)	; Is it a terminal?
	BNEQ	30$			; If NEQ no.

; okay, we have this device UCB in R1, let's change it so that the
; physical UCB is in R1, and the logical UCB is in R2, note that
; these may well be the same thing, only if the terminal is redirected
; will there be any differene.
	MOVL	UCB$L_TL_PHYUCB(R1),R2
	BEQL	21$
	MOVL	R2,R1	; okay, store the physical UCB in R1...

21$:	; Let's get R2 pointing to logical UCB if there is one, else physical
    	MOVL	R1,R2	; assume it's not redirected
	BBC	#DEV$V_RED,UCB$L_DEVCHAR2(R1),22$
	MOVL	UCB$L_TT_LOGUCB(R1),R2
	BNEQ	22$
	MOVL	R1,R2	; this should never occur

22$:	CLRW	R3			; clear the link number
	BBC	#DEV$V_RTT,UCB$L_DEVCHAR2(R1),25$
	MOVW	UCB$W_RTT_LINK(R1),R3	; get the link number

25$:	MOVL	UCB$L_DUETIM(R1),R0	; get duetim
	BEQL	26$			; if zero, save it as zero...
	SUBL3	R0,G^EXE$GL_ABSTIM,R0	; save duetim
26$:	MOVL	R0,(R10)+

27$:	MOVL	UCB$L_PID(R2),R0	; Get internal PID
   	JSB	G^EXE$IPID_TO_EPID	; Convert to extended PID
	MOVL	R0,(R10)+		; Save external PID
	MOVW	R3,(R10)+		; save rtt_link

	MOVL	#SS$_NORMAL,R0		; Success!
	MOVL	G^CTL$GL_PCB,R4		; Get my PCB address again

30$:	PUSHL	R0			; Save the return status
	JSB	G^SCH$IOUNLOCK		; Unlock the I/O database mutex
	SETIPL	#0			; Drop back down from IPL$_ASTDEL
	POPL	R0			; Restore the return status
	RET				; Back to user mode

	.End
