Google
 

Trailing-Edge - PDP-10 Archives - BB-P363B-SM_1985 - mcb/cex/cexsub.m11
There are no other files named cexsub.m11 in the archive.
	.TITLE	CEXSUB - Comm/Exec Miscellaneous Support Routines
	.IDENT	/003160/
	.ENABL	LC

;
;                    COPYRIGHT (c) 1980, 1981, 1982
;                    DIGITAL EQUIPMENT CORPORATION
;                        Maynard, Massachusetts
;
;     This software is furnished under a license and may  be  used
;     and copied only in accordance with the terms of such license
;     and with the inclusion of the above copyright notice.   This
;     software  or any other copies thereof may not be provided or
;     otherwise made available to any other person.  No  title  to
;     and ownership of the software is hereby transferred.
;
;     The information  in  this  software  is  subject  to  change
;     without  notice  and should not be construed as a commitment
;     by DIGITAL EQUIPMENT CORPORATION.
;
;     DIGITAL assumes no responsibility for the use or reliability
;     of  its  software  on  equipment  which  is  not supplied by
;     DIGITAL.
;

;++
; FACILITY: MCB Communications Executive
;
; FUNCTIONAL ABSTRACT:
;
;	This module contains the routines of general use to processes.
;
; ENVIRONMENT: RSX kernel mode with EIS
;
; AUTHOR: Alan D. Peckham, CREATION DATE: 21-MAR-80
;
; MODIFIED BY:
;
;	Alan D. Peckham, 2-Jul-80: VERSION 3.0
; 01	- Change CRSH$ references to CRSH$S.
; 02	- Allow zero count to buffer move routines.
;	  Globalize references to I/O page.
; 03	- Moved global data to seperate module
;	  (module can now be made read-only).
; 04	- Correct shift bug in $CNV18.
; 05	- Update CRSH$S contexts.
; 06	- Correct PIX check in $PDVNM.
; 07	- Fix divide bug in $RND.
; 08	- Verify CCB addresses.
;	Alan D. Peckham, 9-Dec-80: VERSION 3.1
; 09	- Update for MCB V3.1
;	Alan D. Peckham, 30-Jan-80: VERSION 3.2
; 10	- Speed up queueing routines $CMQIN and $CMQIF.
;	  Move $PDVID and $PRCNM to CEX process.
; 11	- Added $CPCTB (CoPy Chain To Buffer).
; 12	- Beware sign extension in $CNV22.
;	  Add $CBLKS routine for CEX process.
; 14	- Corrected copy length bug in $CPTBF.
;	  Round up block estimates in $CBLKS.
; 15	- Fix crash stack context in $RND.
;	  Check for CCB in $CPTBF.
;	  Add new routines $PHY18 and $VIR18 to facilitate
;	  support of UNIBUS mapping.
;	  Remove $CBLKS routine (replaced by following).
;	  Add 32 bit routines:
;	    $ADD32 - Add 16 bit number to 32 bit number.
;	    $MUL32 - multiply two 16 bit numbers to form a 32 bit number.
;	    $DIV32 - divide a 32 bit number by a 16 bit number to get
;		a 16 bit quotient and 16 bit remainder.
;	    $ASH32 - shift a signed 32 bit number.
; 16	- Add new routines $IDSTS and $IDVAL.
;--
	.SBTTL	DECLARATIONS

;
; INCLUDE FILES:
;

	.MCALL	CRSH$S
	.GLOBL	KISAR5

;
; MACROS:
;
;	None
;
; EQUATED SYMBOLS:
;
;	None
;
; OWN STORAGE:
;

	.GLOBL	.RND		; Random number seed.
	.SBTTL	$ADD32	- Add 16 bit number to 32 bit number
;++
; FUNCTIONAL DESCRIPTION:
;
;	Add 16 bit number to 32 bit number
;
; CALLING SEQUENCE:
;
;	CALL	$ADD32
;
; INPUT PARAMETERS:
;
;	R0 = High order 16 bits of number.
;	R1 = Low order 16 bits of number.
;	R2 = Number to add.
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	R0 = High order 16 bits of sum.
;	R1 = Low order 16 bits of sum.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$ADD32::ADD	R2,R1		; Do the sum.
	ADC	R0
	RETURN
	.SBTTL	$ASH32	- Shift signed 32 bit number
;++
; FUNCTIONAL DESCRIPTION:
;
;	Do an arithmetic shift on the given 32 bit number.
;
; CALLING SEQUENCE:
;
;	CALL	$ASH32
;
; INPUT PARAMETERS:
;
;	R0 = High order 16 bits of number.
;	R1 = Low order 16 bits of number.
;	R2 = Number of places to shift.
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	R0 = High order 16 bits of shifted number.
;	R1 = Low order 16 bits of shifted number.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$ASH32::ASHC	R2,R0		; Do the shift.
	RETURN
	.SBTTL	$DIV32	- Divide a 32 bit number
;++
; FUNCTIONAL DESCRIPTION:
;
;	Divide the given 32 bit number to form 16 bit quotient and
;	remainders.
;
; CALLING SEQUENCE:
;
;	CALL	$DIV32
;
; INPUT PARAMETERS:
;
;	R0 = High order 16 bits of dividend.
;	R1 = Low order 16 bits of dividend.
;	R2 = Divisor.
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	R0 = Quotient.
;	R1 = Remainder.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$DIV32::DIV	R2,R0		; Divide.
	RETURN
	.SBTTL	$MUL32	- Multiply to produce a 32 bit number
;++
; FUNCTIONAL DESCRIPTION:
;
;	Multiply to numbers to produce 32 bit number
;
; CALLING SEQUENCE:
;
;	CALL	$MUL32
;
; INPUT PARAMETERS:
;
;	R0 = Multiplicand.
;	R2 = Multipler.
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	R0 = High order 16 bits of result.
;	R1 = Low order 16 bits of result.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$MUL32::MUL	R2,R0		; Multiply.
	RETURN
	.SBTTL	$CMQIF	- Queue CCBs to Front
;++
; FUNCTIONAL DESCRIPTION:
;
;	Insert a chain of CCBs on the front of the given queue.
;
; CALLING SEQUENCE:
;
;	CALL	$CMQIF
;
; INPUT PARAMETERS:
;
;	R4 = Address of CCB chain to insert in queue.
;	R3 = Address of queue list header.
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	None
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$CMQIF::CCBCK$			; Verify CCB address.
	TST	(R4)		; If only one CCB
	BNE	40$		; then
	MOV	(R3)+,(R4)	; link to front of chain.
	BNE	22$		; If adding to empty list
	MOV	R4,(R3)		; then update end of list pointer
22$:	MOV	R4,-(R3)	; and set first CCB in queue.
	RETURN
40$:	PUSH$S	<R5,R4>		; Get some room to work.
42$:	MOV	R4,R5		; Copy CCB address
	MOV	(R5),R4		; and if the last
	BNE	42$		; then
	POP$S	R4		; Get head CCB back
	MOV	(R3)+,(R5)	; and link front of queue to chain.
	BNE	44$		; If adding to empty list
	MOV	R5,(R3)		; then update end of list pointer
44$:	MOV	R4,-(R3)	; and set first CCB in queue.
	POP$S	R5		; Thank you!
	RETURN
	.SBTTL	$CMQIN	- Queue CCBs to Rear
;++
; FUNCTIONAL DESCRIPTION:
;
;	Append a chain of CCBs on the end of the given queue.
;
; CALLING SEQUENCE:
;
;	CALL	$CMQIN
;
; INPUT PARAMETERS:
;
;	R4 = Address of CCB chain to insert in queue.
;	R3 = Address of queue list header.
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	None
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$CMQIN::CCBCK$			; Verify CCB address.
	TST	(R4)		; and if this is the only one
	BNE	40$		; then
	MOV	R4,@2(R3)	; link it to the end of queue
	MOV	R4,2(R3)	; and update last CCB in queue.
	RETURN
40$:	PUSH$S	<R5,R4>		; Get some room to work.
42$:	MOV	R4,R5		; Copy CCB address
	MOV	(R5),R4		; and if the last
	BNE	42$		; then
	MOV	(SP),@2(R3)	; link chain to end of queue
	MOV	R5,2(R3)	; and update last CCB in queue.
	POP$S	<R4,R5>		; Thank you!
	RETURN
	.SBTTL	$CMQRM	- Remove CCB from Queue
;++
; FUNCTIONAL DESCRIPTION:
;
;	Dequeue a CCB from the front of the given queue.
;
; CALLING SEQUENCE:
;
;	CALL	$CMQRM
;
; INPUT PARAMETERS:
;
;	R3 = Address of queue list header.
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	If queue non-empty:
;	    R4 = Address of removed CCB chain.
;	If queue empty:
;	    R4 = undefined.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	C-bit set = Queue is empty.
;	C-bit clear = CCB chain removed from queue.
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$CMQRM::SEC			; Assume failure
	MOV	(R3),R4		; and if list is empty
	BEQ	90$		; then fail.
	MOV	(R4),(R3)	; Otherwise de-link CCB
	BNE	10$		; and if list now empty
	MOV	R3,2(R3)	; then reset last CCB pointer.
10$:	CLR	(R4)		; Reset link.
90$:	RETURN
	.SBTTL	$CNV22	- Convert Bias/Address to 22 Bits
;++
; FUNCTIONAL DESCRIPTION:
;
;	Convert given address doubleword (mapping bias and
;	virtual address) to an 22-bit unibus virtual address.
;
; CALLING SEQUENCE:
;
;	CALL	$CNV22
;
; INPUT PARAMETERS:
;
;	R2 = Relocation bias.
;	R3 = Virtual address.
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	R2 = Bits 16 thru 21 of the unibus address in bits 0 and 3.
;	     The rest of the word is zero.
;	R3 = Low order 16 bits of the unibus address.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$CNV22::PUSH$S	R3		; Save address
	BIC	#^C<160000>,R3	; isolate page bits
	BIC	R3,(SP)		; and remove.
	CMP	#140000,R3	; if not in APR6
	BEQ	10$		; then
	BIS	R3,(SP)		; assume in DSR
	CLR	R2		; with no bias.
10$:	MOV	(SP),R3		; Get bits 12 to 6
	ASH	#-6,R3		; without sign
	BIC	#^C1777,R3	; and
	ADD	R3,R2		; add to bias.
	POP$S	R3		; Get address back
	ASH	#12,R3		; put bits 5 to 0 in top half
	ASHC	#-12,R2		; and pull back down with bias.
	RETURN
	.SBTTL	$CPTBF	- Copy CCB Chain to Unmapped Buffer
;++
; FUNCTIONAL DESCRIPTION:
;
;	Move data from CCB chain to unmapped buffer.
;
; CALLING SEQUENCE:
;
;	MOV	<relocation bias of destination buffer>,-(SP)
;	MOV	<virtual address of destination buffer>,-(SP)
;	CALL	$CPTBF
;	CMP	(SP)+,(SP)+	;(clears the stack)
;
; INPUT PARAMETERS:
;
;	R4 = address of source CCB chain.
;
; IMPLICIT INPUTS:
;
;	On the stack:
;	    2(SP) = virtual address of destination buffer.
;	    4(SP) = relocation bias of destination buffer.
;
; OUTPUT PARAMETERS:
;
;	R0 = number of bytes copied.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$CPTBF::CCBCK$			; Verify CCB address.
	SAV4$S			; Get room to move...
	PUSH$S	@#KISAR5
	MOV	2+S.PARM+0(SP),R0 ; Pick up destination address
	MOV	2+S.PARM+2(SP),@#KISAR5 ; and mapping bias.
	CMP	#140000,R0	; If APR 6 material
	BHI	10$		; then
	SUB	#20000,R0	; adjust for APR 5.
10$:	MOV	R0,-(SP)	; (save starting address)
20$:	MOV	C.CNT(R4),R2
	BEQ	40$
	MAP$	C.BUF+0(R4)
	MOV	C.BUF+2(R4),R1
30$:	MOVB	(R1)+,(R0)+	; Copy the data.
	SOB	R2,30$
40$:	MOV	C.CHN(R4),R4
	BNE	20$
	SUB	(SP)+,R0	; Figure copied length.
	POP$S	@#KISAR5	; Thank you.
90$:	RETURN
	.SBTTL	$MVFBF	- Move Data from Unmapped Buffer
;++
; FUNCTIONAL DESCRIPTION:
;
;	Move data from an unmapped buffer to mapped buffer.
;
; CALLING SEQUENCE:
;
;	MOV	<relocation bias of source buffer>,-(SP)
;	MOV	<virtual address of source buffer>,-(SP)
;	CALL	$MVFBF
;	CMP	(SP)+,(SP)+	;(clears the stack)
;
; INPUT PARAMETERS:
;
;	R2 = virtual address of destination buffer.
;	R3 = count of bytes to move.
;
; IMPLICIT INPUTS:
;
;	On the stack:
;	    2(SP) = virtual address of source buffer.
;	    4(SP) = relocation bias of source buffer.
;	KISAR6 = relocation bias of destination buffer.
;
; OUTPUT PARAMETERS:
;
;	R2 = address of byte beyond last byte inserted in the
;	     destination buffer.
;	R3 = zero.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$MVFBF::
	.IF	NE,D$$BUG
	CMP	#20000,R3	; If copying too much
	BLO	100$		; then better crash.
	.IFTF

	TST	R3		; If nothing to move
	BEQ	90$		; then all finished.
	PUSH$S	<R1,@#KISAR5>	; Get room to move...
	MOV	6(SP),R1	; Pick up source address
	MOV	10(SP),@#KISAR5	; and mapping bias.
	CMP	#140000,R1	; If APR 6 material
	BHI	10$		; then
	SUB	#20000,R1	; adjust for APR 5.
10$:	MOVB	(R1)+,(R2)+	; Copy the data.
	SOB	R3,10$
	POP$S	<@#KISAR5,R1>	; Thank you.
90$:	RETURN

	.IFT
100$:	CRSH$S	CPY		; Copy too long from unmapped buffer
	.ENDC
	.SBTTL	$MVTBF	- Move Data to Unmapped Buffer
;++
; FUNCTIONAL DESCRIPTION:
;
;	Move data from a mapped buffer to an unmapped buffer.
;
; CALLING SEQUENCE:
;
;	MOV	<relocation bias of destination buffer>,-(SP)
;	MOV	<virtual address of destination buffer>,-(SP)
;	CALL	$MVTBF
;	CMP	(SP)+,(SP)+	;(clears the stack)
;
; INPUT PARAMETERS:
;
;	R2 = virtual address of source buffer.
;	R3 = count of bytes to move.
;
; IMPLICIT INPUTS:
;
;	On the stack:
;	    2(SP) = virtual address of destination buffer.
;	    4(SP) = relocation bias of destination buffer.
;	KISAR6 = relocation bias of source buffer.
;
; OUTPUT PARAMETERS:
;
;	R2 = address of byte beyond last byte inserted in the
;	     source buffer.
;	R3 = zero.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$MVTBF::
	.IF	NE,D$$BUG
	CMP	#20000,R3	; If copying too much
	BLO	100$		; then better crash.
	.IFTF

	TST	R3		; If nothing to move
	BEQ	90$		; then all finished.
	PUSH$S	<R1,@#KISAR5>	; Get room to move...
	MOV	6(SP),R1	; Pick up destination address
	MOV	10(SP),@#KISAR5	; and mapping bias.
	CMP	#140000,R1	; If APR 6 material
	BHI	10$		; then
	SUB	#20000,R1	; adjust for APR 5.
10$:	MOVB	(R2)+,(R1)+	; Copy the data.
	SOB	R3,10$
	POP$S	<@#KISAR5,R1>	; Thank you.
90$:	RETURN

	.IFT
100$:	CRSH$S	CPY		; Copy too long from unmapped buffer
	.ENDC
	.SBTTL	$PHY18	- Convert Bias/Address to 18 Bit UNIBUS Address
;++
; FUNCTIONAL DESCRIPTION:
;
;	Convert given address doubleword (mapping bias and
;	virtual address) to an 18-bit UNIBUS physical address.
;
; CALLING SEQUENCE:
;
;	CALL	$PHY18
;
; INPUT PARAMETERS:
;
;	R2 = Relocation bias.
;	R3 = Virtual address.
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	R2 = Bits 16 thru 17 of the UNIBUS address in bits 0 and 1.
;	     The rest of the word is zero.
;	R3 = Low order 16 bits of the UNIBUS address.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$PHY18::MOV	R3,-(SP)	; Save address
	BIC	#^C<160000>,R3	; isolate page bits
	BIC	R3,(SP)		; and remove.
	CMP	#140000,R3	; if not in APR6
	BEQ	10$		; then
	BIS	R3,(SP)		; assume in DSR
	CLR	R2		; with no bias.
10$:	MOV	(SP),R3		; Get bits 12 to 6
	ASH	#-6,R3		; without sign
	BIC	#^C1777,R3	; and
	ADD	R2,R3		; add to bias.
	MOV	#.UBMTA,R2	; Unibus mapping data base pointer
15$:	MOV	(R2),R2		; Next data base entry
	BEQ	50$		; Assume unibus mapping turned off
	CMP	R3,2(R2)	; Low memory limit
	BLO	15$		; Under lower limit. Assume DSR
	CMP	R3,4(R2)	; Upper limit
	BHIS	15$		; Above upper limit. Try next
	SUB	2(R2),R3	; Relative to lower limit
	MOVB	6(R2),R2	; Base unibus mapping register.
	ASH	#7,R2		; Shift to right position
50$:	ADD	R3,R2		; Remainder is block number in UBA
	MOV	(SP)+,R3	; Get address back
	ASH	#12,R3		; put bits 5 to 0 in top half
	ASHC	#-12,R2		; and pull back down with bias.
	RETURN
	.SBTTL	$RND	- Get a Random Number
;++
; FUNCTIONAL DESCRIPTION:
;
;	Provide a random integer from a uniform distribution on the
;	interval between 0 (closed) and n (open).
;
; CALLING SEQUENCE:
;
;	CALL	$RND
;
; INPUT PARAMETERS:
;
;	R0 = upper limit (n).
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	R0 = random integer.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$RND::	.IF	NE,D$$BUG
	TST	R0		; (crash if invalid interval)
	BLE	100$
	.IFTF

	SAV5$S
	MOV	#.RND,R5	; Get address of seed
	MOV	(R5)+,R3	; pick up seed
	MOV	(R5),R4		; and
	ASL	R4		; multiply by 200003 = 65539.
	ROL	R3		; (a prime number)
	ADD	(R5),R4
	ADC	R3
	ADD	(R5),R3
	ADD	-(R5),R3
	BIC	#100000,R3	; Make it positive
	MOV	R3,(R5)+	; and save it
	MOV	R4,(R5)		; as the new seed.
	PUSH$S	R0
	ASL	R4
	ROL	R3
	MOV	R4,R2		; Copy multiplicand.
	MOV	R3,R1
	CLR	R0
	MOV	#16.,R5
10$:	ASL	(SP)
	DEC	R5
	BCC	10$
	BEQ	80$
20$:	ASL	R2		; Multiply by 2.
	ROL	R1
	ROL	R0
	ASL	(SP)		; Check multiplier
	BCC	30$		; and if bit set
	ADD	R4,R2		; then add multiplicand
	ADC	R1		; to result.
	ADD	R3,R1
	ADC	R0
30$:	SOB	R5,20$
80$:	POP$S	,1
	RETURN

	.IFT
100$:	CRSH$S	RND		; Invalid random number interval
	.ENDC
	.SBTTL	$IDSTS	- Identify a Status Value from a Table
;++
; FUNCTIONAL DESCRIPTION:
;
;	Locate the given BLISS status code in a table and return
;	an index into that table.  Fields STS$V_COND_ID and
;	STS$V_CUST_DEF are compared.
;	
;
; CALLING SEQUENCE:
;
;	CALL	$IDSTS
;
; INPUT PARAMETERS:
;
;	R0 = address of plit of status codes
;	R1 = value to compare
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	R0 = 0 (if no match)
;	     index into table + 1 (if match)
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$IDSTS::SAV2$S
	MOV	R0,-(SP)
	MOV	-2(R0),R2
	BEQ	20$
	BIC	#^C<137770>,R1
10$:	MOV	(R0)+,-(SP)
	BIC	#^C<137770>,(SP)
	CMP	(SP)+,R1
	BEQ	30$
	SOB	R2,10$
20$:	MOV	(SP),R0
30$:	SUB	(SP)+,R0
	ASR	R0
	RETURN
	.SBTTL	$IDVAL	- Identify a Value from a Table
;++
; FUNCTIONAL DESCRIPTION:
;
;	Locate the given value in a table and return an index
;	into that table.
;
; CALLING SEQUENCE:
;
;	CALL	$IDVAL
;
; INPUT PARAMETERS:
;
;	R0 = address of plit of values to match
;	R1 = value to compare
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	R0 = 0 (if no match)
;	     index into table + 1 (if match)
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	None
;
; SIDE EFFECTS:
;
;	None
;--

	.PSECT	$CODE$,I,RO
$IDVAL::SAV2$S
	MOV	R0,-(SP)
	MOV	-2(R0),R2
	BEQ	20$
10$:	CMP	R1,(R0)+
	BEQ	30$
	SOB	R2,10$
20$:	MOV	(SP),R0
30$:	SUB	(SP)+,R0
	ASR	R0
	RETURN
	.SBTTL	$VIR18	- Convert 18 Bit UNIBUS Address to Bias/Address
;++
; FUNCTIONAL DESCRIPTION:
;
;	Convert given 18-bit UNIBUS physical address to a virtual address
;	relative to the current KISAR6 mapping bias.
;
; CALLING SEQUENCE:
;
;	CALL	$VIR18
;
; INPUT PARAMETERS:
;
;	R0 = Bits 16 thru 17 of the UNIBUS address in bits 0 and 1.
;	     The rest of the word is zero.
;	R1 = Low order 16 bits of the UNIBUS address.
;
; IMPLICIT INPUTS:
;
;	None
;
; OUTPUT PARAMETERS:
;
;	R0 = Virtual address.
;
; IMPLICIT OUTPUTS:
;
;	None
;
; CONDITION CODES:
;
;	C-bit clear = virtual address relative to KISAR6
;	C-bit set =   Unibus address could not be mapped relative
;		      to the current KISAR6.
;
; SIDE EFFECTS:
;
;	Register R1 is not preserved.
;--
	.GLOBL	KISAR6

	.PSECT	$CODE$,I,RO
$VIR18::TST	.UBMTA		; Is Unibus mapping in effect
	BEQ	10$		; No
	ASHC	#3,R0		; Unibus mapping register number
	ASH	#2,R0		; Relative Unibus mapping reg address
	ASH	#-3,R1		; Address relative to UBMR.
	BIC	#160000,R1	; Clear hi bits
	ADD	UBMPR(R0),R1	; Add low order physical (UBMR) address
	MOV	UBMPR+2(R0),R0	; High order physical address
	ADC	R0		; Add carry from above
10$:	ASHC	#16.-6,R0	; Get bias
	SUB	@#KISAR6,R0	; and block offset.
	BMI	80$		; if
	CMP	#200,R0		; within range
	BLOS	80$		; then
	ADD	#1400,R0	; place in APR6
70$:	ASHC	#6.,R0		; to get virtual address.
	RETURN
80$:	ADD	@#KISAR6,R0	; (not in APR6)
	BIS	#176000,R0	; Force carry
	BR	70$

	.END