Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!lll-crg!ames!ucbcad!ucbvax!CINCOM.UMD.EDU!todd
From: todd@CINCOM.UMD.EDU ("TODD AVEN")
Newsgroups: mod.computers.vax
Subject: OBSERVE.MAR Part 1 of 1.
Message-ID: <8612172149.AA21379@ucbvax.Berkeley.EDU>
Date: Wed, 17-Dec-86 00:25:00 EST
Article-I.D.: ucbvax.8612172149.AA21379
Posted: Wed Dec 17 00:25:00 1986
Date-Received: Thu, 18-Dec-86 03:54:06 EST
Sender: daemon@ucbvax.BERKELEY.EDU
Reply-To: "TODD AVEN" 
Organization: The ARPA Internet
Lines: 850
Approved: info-vax@sri-kl.arpa

Following the -*- cut here -*- is the VAX/MACRO program
OBSERVE.MAR.  I didn't write it, so I can't answer any
questions about it (gasp! I haven't even looked at the code).

Use in good taste, please.

-? send(message(following),from(todd),to(Netlandiers)).
			-*- cut here -*-
	.TITLE		OBSERVE

	.LIBRARY	/SYS$LIBRARY:LIB.MLB/

	.PAGE
	.SUBTITLE	DEFINITIONS

	$CRBDEF		GLOBAL
	$DDBDEF		GLOBAL
	$DVIDEF		GLOBAL
	$IDBDEF		GLOBAL
	$IODEF		GLOBAL
	$IPLDEF		GLOBAL
	$IRPDEF		GLOBAL
	$PRDEF		GLOBAL
	$PRIDEF		GLOBAL
	$RSNDEF		GLOBAL
	$SSDEF		GLOBAL
	$TTYDEF		GLOBAL
	$TTDEF		GLOBAL
	$TT2DEF		GLOBAL
	$UBADEF		GLOBAL
	$UCBDEF		GLOBAL
	$VECDEF		GLOBAL
	$TTYMACS	
	$TTYDEFS	GLOBAL

	.PAGE
	.SUBTITLE	PARAMETERS

TERM_LENGTH     =  64
RESPONSE_LENGTH =   1
HEADER          =  12
DYN_C_CODE      = 120

GREATER_THAN_ZERO = ^B1100
NEGATIVE          = ^B1000
ZERO              = ^B0100

	.PAGE
	.SUBTITLE	BUFFERS

CHANNEL:
	.BLKW		1

SYS_INPUT:
	.ASCII		/SYS$INPUT/
SYS_INPUT_LENGTH        = .- SYS_INPUT

TERM_PROMPT:
	.ASCII		/enter target terminal /
TERM_PROMPT_LENGTH           = .- TERM_PROMPT

PROMPT_BUFFER:
	.BLKB		TERM_LENGTH

TARGET_TERMINAL:
	.BLKB		TERM_LENGTH

MY_TERMINAL:
	.BLKB		TERM_LENGTH


;I need to substitute tests for 'X' in the terminal name with a test of
;this byte (MY_TERM_TYPE).  I should also validate the target terminal
;type (DT$_DZ11 or DT$_DMF32).

TARGET_TERM_TYPE:
	.BYTE		0

MY_TERM_TYPE:
	.BYTE		0	

TARGET_PID:
	.BLKL		1

TARGET_CLASS:
	.BLKL		1

TARGET_UCB_ADDRESS:
	.BLKL		1

TARGET_UCB_PRTCTL:
	.BLKW		1

NPP_ADDRESS:
	.BLKL		1

ALLOCATED_SIZE:
	.BLKL		1

RESPONSE_BUFFER:
	.BLKB		RESPONSE_LENGTH

EXIT_MESSAGE_BUFFER:
	.BYTE		27
	.BYTE		91
	.BYTE		72
	.BYTE		27
	.BYTE		91
	.BYTE		74
	.ASCII		?enter CTRL/Y to exit?
	.BYTE		13
	.BYTE		10
EXIT_MESSAGE_LENGTH = .- EXIT_MESSAGE_BUFFER

ROW:	.LONG	24
COLUMN:	.LONG	1

MY_UCB_ADDRESS:
	.LONG		0

PUTNXT_ADDRESS:
	.LONG		0

GETNXT_ADDRESS:
	.LONG		0

PORT_ADDRESS:
	.LONG		0

NEW_PUTNXT_ADDRESS:
	.BLKL		1

NEW_GETNXT_ADDRESS:
	.BLKL		1

NEW_PORT_ADDRESS:
	.BLKL		1

USER_RUNDOWN_ADDRESS:
	.BLKL		1

CONTROL_Y_MASK:
	.LONG		^X02000000

QIO_IOSB:
	.BLKQ		1

TERMINAL_CHAR:
	.BLKQ	1


	.PAGE
	.SUBTITLE	GETDVI ITEM LIST

GETDVI_ITEM_LIST:
	.WORD		TERM_LENGTH
	.WORD		DVI$_TT_PHYDEVNAM
DVI_TERM_ADDR:
	.ADDRESS	TARGET_TERMINAL
	.LONG		0

	.WORD		4
	.WORD		DVI$_PID
	.ADDRESS	TARGET_PID
	.LONG		0

	.WORD		4
	.WORD		DVI$_DEVCLASS
	.ADDRESS	TARGET_CLASS
	.LONG		0

	.LONG		0


	.PAGE
	.SUBTITLE	DESCRIPTORS


SYS_INPUT_DESCR:
	.WORD		SYS_INPUT_LENGTH
	.BLKW		1
	.ADDRESS	SYS_INPUT

TERM_PROMPT_DESCR:
	.WORD		TERM_PROMPT_LENGTH
	.BLKW		1
	.ADDRESS	TERM_PROMPT

TARGET_TERM_DESCR:
	.WORD		TERM_LENGTH
	.BLKW		1
	.ADDRESS	TARGET_TERMINAL


	.PAGE
	.SUBTITLE	OBSERVE

	.ENTRY		OBSERVE, ^M<>

	BSBW		INITIAL
	CMPL		#SS$_NORMAL, R0
	BEQLU		10$
	BRW		EXIT
10$:
	$CMKRNL_S	ROUTIN = INITIALIZE_UCBS
	BLBS		R0, 20$
	BRW		EXIT
20$:
	;disable CTRL/Y

	PUSHAL		CONTROL_Y_MASK
	CALLS		#1, G^LIB$DISABLE_CTRL
	BLBS		R0, 30$
	BRW		EXIT
30$:
	;clear screen with write

	$QIOW_S		FUNC   = #IO$_WRITEVBLK,-
			CHAN   = CHANNEL,-
			IOSB   = QIO_IOSB,-
			P1     = EXIT_MESSAGE_BUFFER,-
			P2     = #EXIT_MESSAGE_LENGTH
	BLBC		R0, EXIT
	BLBC		QIO_IOSB, EXIT

	;modify target UCB

	$CMKRNL_S	ROUTIN = MODIFY_TARGET_UCB
	BLBC		R0, EXIT

	;establish CTRL/Y AST to execute termination routine

	$QIOW_S		FUNC   = #IO$_SETMODE!IO$M_CTRLYAST,-
			CHAN   = CHANNEL,-
			IOSB   = QIO_IOSB,-
			P1     = TERMINATION
	BLBC		R0, EXIT
	BLBC		QIO_IOSB, EXIT

	$HIBER_S

EXIT:
	PUSHL		R0
	PUSHAL		CONTROL_Y_MASK
	CALLS		#1, G^LIB$ENABLE_CTRL

	BBS		#TT$V_NOBRDCST, TERMINAL_CHAR, 10$

	$QIOW_S		FUNC = #IO$_SETMODE,-
			CHAN = CHANNEL,-
			P1   = TERMINAL_CHAR
10$:
	$DASSGN_S	CHAN = CHANNEL

	$EXIT_S		(SP)+


	.PAGE
	.SUBTITLE	INITIAL


INITIAL:

	PUSHL		#0			;prompt only if string absent
	PUSHAL		TARGET_TERM_DESCR	;don't need out length
	PUSHAQ		TERM_PROMPT_DESCR
	PUSHAQ		TARGET_TERM_DESCR

	;obtain target terminal name

	CALLS		#4, G^LIB$GET_FOREIGN
	BLBS		R0, 10$

	BRW		INITIAL_EXIT

10$:
	;make sure it's a valid device

	$GETDVIW_S	DEVNAM = TARGET_TERM_DESCR,-
			ITMLST = GETDVI_ITEM_LIST
	BLBS		R0, 12$
11$:
	BRW		INITIAL_EXIT
12$:
	CMPL		#SS$_NOSUCHDEV, R0
	BEQL		11$

	;make sure the device is being used
15$:
	TSTB		TARGET_PID
	BNEQU		20$

	MOVL		#SS$_NONEXPR, R0
	BRW		INITIAL_EXIT

20$:
	;assign a channel to my terminal

	$ASSIGN_S	DEVNAM = SYS_INPUT_DESCR,-
			CHAN   = CHANNEL
	BLBS		R0, 25$
	BRW		INITIAL_EXIT

	;get my terminal name
25$:
	MOVAL		MY_TERMINAL, DVI_TERM_ADDR
	MOVL		#0, DVI_TERM_ADDR + 4

	$GETDVIW_S	CHAN   = CHANNEL,-
			ITMLST = GETDVI_ITEM_LIST
	BLBC		R0, INITIAL_EXIT

	MOVL		TARGET_TERMINAL + 1, TARGET_TERMINAL
	MOVL		MY_TERMINAL + 1, MY_TERMINAL

	;make sure I'm not observing my terminal

	CMPL		MY_TERMINAL, TARGET_TERMINAL
	BNEQU		30$

	MOVL		#SS$_NONEXPR, R0
	BRB		INITIAL_EXIT

	;set my terminal to no-broadcast
30$:
	$QIOW_S		FUNC = #IO$_SENSEMODE,-
			CHAN = CHANNEL,-
			P1   = TERMINAL_CHAR
	BLBC		R0, INITIAL_EXIT

	BBS		#TT$V_NOBRDCST, TERMINAL_CHAR, INITIAL_EXIT

	MOVQ		TERMINAL_CHAR, QIO_IOSB
	BISL2		#TT$M_NOBRDCST, QIO_IOSB + 4

	$QIOW_S		FUNC = #IO$_SETMODE,-
			CHAN = CHANNEL,-
			P1   = QIO_IOSB

INITIAL_EXIT:
	RSB


	.PAGE
	.SUBTITLE	INITIALIZE UCBS


	.ENTRY		INITIALIZE_UCBS, ^M

	BSBW		FIND_UCBS

	;check to see if this terminal is already OBSERVEd

	MOVL		MY_UCB_ADDRESS, R1
	CMPL		UCB$L_TT_PUTNXT(R1), PUTNXT_ADDRESS
	BEQLU		10$
5$:
	MOVL		#SS$_ILLIOFUNC, R0
	BRB		20$
10$:
	MOVL		TARGET_UCB_ADDRESS, R0
	CMPB		UCB$W_TT_SPEED(R1), UCB$W_TT_SPEED(R0)
	BLSSU		5$
15$:
	BSBW		PUT_ROUTINE_IN_NPP
20$:
	RET

	.PAGE
	.SUBTITLE	FIND_UCBS

FIND_UCBS:

	MOVL		G^IOC$GL_DEVLIST, R6

10$:
	CMPC3		#3, DDB$T_NAME+1(R6), TARGET_TERMINAL
	BNEQU		30$

	CLRL		R7
	CLRL		R8
	SUBB3		#48, TARGET_TERMINAL + 3, R7

	MOVL		DDB$L_UCB(R6), R9
	BRB		25$

20$:
	MOVL		UCB$L_LINK(R9), R9
25$:
	AOBLEQ		R7, R8, 20$

;	MOVL		UCB$L_CRB(R9), R10
;	MOVB		CRB$B_TT_TYPE(R10), TARGET_TERM_TYPE

	MOVL		UCB$L_TT_PUTNXT(R9), PUTNXT_ADDRESS
	MOVL		UCB$L_TT_GETNXT(R9), GETNXT_ADDRESS
	MOVL		UCB$L_TT_PORT(R9), PORT_ADDRESS
	MOVW		UCB$W_TT_PRTCTL(R9), TARGET_UCB_PRTCTL

	MOVL		R9, TARGET_UCB_ADDRESS

	TSTL		MY_UCB_ADDRESS
	BNEQU		FIND_EXIT

30$:
	CMPC3		#3, DDB$T_NAME+1(R6), MY_TERMINAL
	BNEQU		60$

	CLRL		R7
	CLRL		R8
	SUBB3		#48, MY_TERMINAL + 3, R7

	MOVL		DDB$L_UCB(R6), R9
	BRB		45$

40$:
	MOVL		UCB$L_LINK(R9), R9
45$:
	AOBLEQ		R7, R8, 40$

	MOVL		R9, MY_UCB_ADDRESS

;	MOVL		UCB$L_CRB(R9), R10
;	MOVB		CRB$B_TT_TYPE(R10), MY_TERM_TYPE

	TSTL		TARGET_UCB_ADDRESS
	BNEQU		FIND_EXIT

60$:
	MOVL		DDB$L_LINK(R6), R6
	BEQLU		FIND_EXIT
	BRW		10$

FIND_EXIT:
	RSB

	.PAGE
	.SUBTITLE	PUT_ROUTINE_IN_NPP

PUT_ROUTINE_IN_NPP:

	CMPB		#^A/X/, MY_TERMINAL + 1
	BNEQU		10$

	MOVL		#DMF_ROUTINE_LENGTH, R1
	BRB		20$
10$:
	MOVL		#DZ_ROUTINE_LENGTH, R1
20$:
	MTPR		IPL_TWO, S^#PR$_IPL
	JSB		G^EXE$ALONONPAGED
	MTPR		#0, S^#PR$_IPL

	;establish image rundown routine

	MOVL		G^CTL$GL_USRUNDWN, USER_RUNDOWN_ADDRESS

	MOVAL		RESET_UCBS, G^CTL$GL_USRUNDWN

	BRB		AROUND

IPL_TWO:
	.BYTE		2

AROUND:
	BLBS		R0, 2$
	BRW		PUT_EXIT
2$:
	MOVL		R2, NPP_ADDRESS

	MOVL		PUTNXT_ADDRESS, (R2)+
	MOVL		MY_UCB_ADDRESS, (R2)+

	;mark block for easy deallocation

	MOVW		R1, (R2)+
	MOVW		#DYN_C_CODE, (R2)+

	;move GETNXT address and port address

	MOVL		GETNXT_ADDRESS, (R2)+

	MOVL		@PORT_ADDRESS, (R2)+

	;save start of vector table in R8 for modifying UCB

	MOVL		R2, NEW_PORT_ADDRESS

	;calculate address of PORT_STARTIO vector and move into vector table

	CMPB		#^A/X/, MY_TERMINAL + 1
	BNEQU		3$

	ADDL3		NPP_ADDRESS, #DMF_STARTIO_DISPLACEMENT, (R2)+
	BRB		4$
3$:
	ADDL3		NPP_ADDRESS, #DZ_STARTIO_DISPLACEMENT, (R2)+
4$:
	;loop to move the other port vectors

	MOVL		#1, R0
5$:
	MOVL		@PORT_ADDRESS[R0], (R2)+
	AOBLSS		#14, R0, 5$

	;move address of PUTNXT code into R6 for modifying UCB

	MOVL		R2, NEW_PUTNXT_ADDRESS

	;move code into system buffer,  calculate GETNXT address (in R7)

	CMPB		#^A/X/, MY_TERMINAL + 1
	BNEQU		10$

	MOVC3		#DMF_CODE_LENGTH, DMF_PUTNXT_ROUTINE, (R2)
	ADDL3		#DMF_GETNXT_DISPLACEMENT, NEW_PUTNXT_ADDRESS,-
			NEW_GETNXT_ADDRESS
	BRB		20$

10$:
	MOVC3		#DZ_CODE_LENGTH, DZ_PUTNXT_ROUTINE, (R2)
	ADDL3		#DZ_GETNXT_DISPLACEMENT, NEW_PUTNXT_ADDRESS,-
			NEW_GETNXT_ADDRESS
20$:
	MOVL		#SS$_NORMAL, R0

PUT_EXIT:
	RSB

	.PAGE
	.SUBTITLE	MODIFY TARGET UCB

	.ENTRY		MODIFY_TARGET_UCB, ^M<>

	MOVL		TARGET_UCB_ADDRESS, R2

	MTPR		IPL_21, S^#PR$_IPL

	MOVL		NEW_PUTNXT_ADDRESS, UCB$L_TT_PUTNXT(R2)
	MOVL		NEW_GETNXT_ADDRESS, UCB$L_TT_GETNXT(R2)
	MOVL		NEW_PORT_ADDRESS, UCB$L_TT_PORT(R2)

	;clear DMA bit to force single character and burst output

	BICW2		#TTY$M_PC_DMAENA, UCB$W_TT_PRTCTL(R2)

	MTPR		#0, S^#PR$_IPL

	MOVL		#SS$_NORMAL, R0
	RET

IPL_21:
	.BYTE		21


	.PAGE
	.SUBTITLE	START OF DMF ROUTINE


START_OF_DMF_ROUTINE:

DMF_PUTNXT_ADDRESS:
	.BLKL		1

DMF_MY_UCB_ADDRESS:
	.BLKL		1

	.BLKL		1	;holds position of 3rd longword of header

DMF_GETNXT_ADDRESS:
	.BLKL		1	;moved to system buffer via MOVL

DMF_PORT_VECTOR:
	.BLKL		1

DMF_PORT_VECTOR_TABLE:
	.BLKL		14	;new vector table

DMF_PUTNXT_ROUTINE:

	PUSHR		#^M

	MOVL		DMF_MY_UCB_ADDRESS, R6

	MOVL		UCB$L_CRB(R6), R7
	MOVL		@CRB$L_INTD + VEC$L_IDB(R7), R7

	PUSHAL		DMF_START_IO			;return to output rtn
	JMP		@DMF_PUTNXT_ADDRESS		;perform code

DMF_GETNXT_ROUTINE:
DMF_GETNXT_DISPLACEMENT = .-DMF_PUTNXT_ROUTINE

	PUSHR		#^M

	MOVL		DMF_MY_UCB_ADDRESS, R6

	MOVL		UCB$L_CRB(R6), R7
	MOVL		@CRB$L_INTD + VEC$L_IDB(R7), R7

	JSB		@DMF_GETNXT_ADDRESS		;perform routine
DMF_START_IO:
	BLEQ		10$				;none or string output

	BISW3		#^X4040, UCB$W_UNIT(R6), (R7)	;select silo transmit
	MOVB		R3, 6(R7)			;output character

	BICPSW		#GREATER_THAN_ZERO		;reset CC
	BRB		91$

10$:
	BEQL		91$				;no output
	MOVW		UCB$W_TT_OUTLEN(R5), UCB$W_TT_OUTLEN(R6)
	MOVL		UCB$L_TT_OUTADR(R5), UCB$L_TT_OUTADR(R6)
	BISW3		#^X4040, UCB$W_UNIT(R6), (R7)
	MOVZBL		6(R7), R8			;get silo depth
	SUBL3		R8, #32, R8			;convert to # of slots
	MOVZWL		UCB$W_TT_OUTLEN(R6), R9		;get length of transfer
	CMPW		R9, R8				;compare slots and size
	BLEQU		50$
	MOVZBL		R8, R9				;maximize with slots
50$:
	MOVL		UCB$L_TT_OUTADR(R6), R10	;autoincrement R10
	ADDL		R9, UCB$L_TT_OUTADR(R6)		;update pointer
	SUBW		R9, UCB$W_TT_OUTLEN(R6)		;and count
	BEQL		60$
	BISW		#TTY$M_TANK_BURST,-
			UCB$W_TT_HOLD(R6)
60$:
	BLBC		R9, 70$				;branch if even
	MOVB		(R10)+, 6(R7)			;output single byte
	DECL		R9
	BEQL		90$
70$:
	ASHL		#-1, R9, R9			;convert to word count
75$:
	MOVW		(R10)+, 6(R7)
	NOP
	NOP
	NOP
	SOBGTR		R9, 75$
90$:
	TSTL		DMF_MY_UCB_ADDRESS		;reset CC negative
91$:
	POPR		#^M

	RSB

DMF_STARTIO_ROUTINE:
DMF_STARTIO_DISPLACEMENT = .-START_OF_DMF_ROUTINE

	BEQL		90$

	;save PSL on stack

	MOVPSL		-28(SP)

	;load return address for RSB in above routine

	PUSHL		DMF_PORT_VECTOR

	PUSHR		#^M

	;save condition codes and set branch address to above routine (REI)

	TSTL		-(SP)
	PUSHAL		DMF_START_IO

	MOVL		DMF_MY_UCB_ADDRESS, R6

	MOVL		UCB$L_CRB(R6), R7
	MOVL		@CRB$L_INTD + VEC$L_IDB(R7), R7

	;restore condition codes and branch

	REI

90$:
	JMP		@DMF_PORT_VECTOR


DMF_CODE_LENGTH = .-DMF_PUTNXT_ROUTINE
DMF_ROUTINE_LENGTH = .- START_OF_DMF_ROUTINE


	.PAGE
	.SUBTITLE	START OF DZ ROUTINE


START_OF_DZ_ROUTINE:

DZ_PUTNXT_ADDRESS:
	.BLKL		1

DZ_MY_UCB_ADDRESS:
	.BLKL		1

	.BLKL		1	;holds position of 3rd longword of header

DZ_GETNXT_ADDRESS:
	.BLKL		1	;moved to system buffer via MOVL  DMF_GETNXT...

DZ_PORT_VECTOR:
	.BLKL		1

DZ_PORT_VECTOR_TABLE:
	.BLKL		14

DZ_PUTNXT_ROUTINE:

	PUSHR		#^M

	MOVL		DZ_MY_UCB_ADDRESS, R6

	MOVL		UCB$L_CRB(R6), R7
	MOVL		@CRB$L_INTD + VEC$L_IDB(R7), R7

	PUSHAL		DZ_START_IO			;return to output rtn
	JMP		@DZ_PUTNXT_ADDRESS		;perform routine


DZ_GETNXT_ROUTINE:
DZ_GETNXT_DISPLACEMENT = .-DZ_PUTNXT_ROUTINE

	PUSHR		#^M

	MOVL		DZ_MY_UCB_ADDRESS, R6

	MOVL		UCB$L_CRB(R6), R7
	MOVL		@CRB$L_INTD + VEC$L_IDB(R7), R7

	JSB		@DZ_GETNXT_ADDRESS		;perform routine

	TSTB		UCB$B_TT_OUTYPE(R5)		;anything to output??
DZ_START_IO:
	BLEQ		10$				;none or string output

	MOVB		R3, UCB$W_TT_HOLD(R6)		;save character in tank
	BISW		#TTY$M_TANK_HOLD,-
			UCB$W_TT_HOLD(R6)		;signal char in tank
	BISW		UCB$W_TT_UNITBIT(R6), 4(R7)	;enable line

	BICPSW		#GREATER_THAN_ZERO		;reset CC positive
	BRW		90$				;exit

10$:
	BEQL		90$				;no character - exit
	MOVL		UCB$L_TT_OUTADR(R5), UCB$L_TT_OUTADR(R6)	;addr
	MOVW		UCB$W_TT_OUTLEN(R5), UCB$W_TT_OUTLEN(R6)	;len
	BISW		#TTY$M_TANK_BURST,-
			UCB$W_TT_HOLD(R6)		;signal burst
	BISW		UCB$W_TT_UNITBIT(R6), 4(R7)	;enable line

	TSTL		DZ_MY_UCB_ADDRESS		;reset CC negative
90$:
	POPR		#^M
	RSB

DZ_STARTIO_ROUTINE:
DZ_STARTIO_DISPLACEMENT = .-START_OF_DZ_ROUTINE

	;save PSL on stack

	MOVPSL		-20(SP)

	;push return address of above routine

	PUSHL		DZ_PORT_VECTOR

	PUSHR		#^M

	;save condition codes and set branch address to above routine (REI)

	TSTL		-(SP)
	PUSHAL		DZ_START_IO

	MOVL		DZ_MY_UCB_ADDRESS, R6		;get my UCB
	MOVL		UCB$L_CRB(R6), R7		;find my
	MOVL		@CRB$L_INTD + VEC$L_IDB(R7), R7	;CSR

	;restore condition codes and branch

	REI

DZ_CODE_LENGTH = .-DZ_PUTNXT_ROUTINE
DZ_ROUTINE_LENGTH = .- START_OF_DZ_ROUTINE



	.PAGE
	.SUBTITLE	TERMINATION ROUTINE

	.ENTRY		TERMINATION, ^M<>

	PUSHAL		CONTROL_Y_MASK
	CALLS		#1, G^LIB$ENABLE_CTRL

	pushal		column
	pushal		row
	calls		#2, G^lib$set_cursor

	BBS	#TT$V_NOBRDCST, TERMINAL_CHAR, 10$

	$QIOW_S		FUNC = #IO$_SETMODE,-
			CHAN = CHANNEL,-
			P1   = TERMINAL_CHAR
10$:
	$DASSGN_S	CHAN = CHANNEL

	;force immediate image rundown

	$EXIT_S		R0

	RET

	.PAGE
	.SUBTITLE	RESET UCBS

RESET_UCBS:

	MOVL		TARGET_UCB_ADDRESS, R2

	MOVL		NPP_ADDRESS, R0

	MTPR		IPL_TWENTY_ONE, S^#PR$_IPL

	MOVL		PUTNXT_ADDRESS, UCB$L_TT_PUTNXT(R2)
	MOVL		GETNXT_ADDRESS, UCB$L_TT_GETNXT(R2)
	MOVL		PORT_ADDRESS, UCB$L_TT_PORT(R2)
	MOVW		TARGET_UCB_PRTCTL, UCB$W_TT_PRTCTL(R2)

	MTPR		#2, S^#PR$_IPL

	JSB		G^EXE$DEANONPAGED

	MTPR		#0, S^#PR$_IPL

	;clear specified rundown routine

	MOVL		USER_RUNDOWN_ADDRESS, G^CTL$GL_USRUNDWN

	BRB		AROUND_1

IPL_TWENTY_ONE:
	.BYTE		21

AROUND_1:
	RSB
	.END		OBSERVE
------