#-h- vaini.mac       2155  asc  01-apr-81 11:44:13  [002,005]
	.title	vadrv
	.sbttl	symbols, macros and global locations
	.mcall	pktdf$,clkdf$,tcbdf$,ucbdf$,qiosy$
	pktdf$
	clkdf$
	tcbdf$
	ucbdf$
	qiosy$
tintpt=2		; seconds between clock interrupts
c.ucb=c.ar5+2
i.p1=i.prm
i.p2=i.prm+2
i.p3=i.prm+4
i.p4=i.prm+6
i.p5=i.prm+10
i.p6=i.prm+12
ok=0
err=-3
created=1
accessed=2
buf_ovf=-1
tim_out=-2
normal=0
interrupt=1
	.macro	jeq	dest,?lab
	bne	lab
	jmp	dest
lab:
	.endm	jeq
	.psect	.prog.,rw,i,lcl,rel,con
$vatbl::
	.word	vaini
	.word	$intxt
	.word	$intxt
	.word	vapwf
;
;	global variables referenced by c routines
;
aether::	.word	0
buf_list::	.word	buf0
msg_list::	.word	hdr0
nam_list::	.word	ltl0
aet_name::	.word	nambuf
password::	.word	pasbuf
pcb::		.word	0
nml_ast::	.word	0
int_ast::	.word	0
ast_parm::	.word	0
if_access::	.word	0
type::		.word	0
descript::	.word	0
buf_ptr::	.word	0
buf_size::	.word	0
life_tim::	.word	0
status::	.word	0
;
;	buffers to hold aether name and password passed by user
;
nambuf:	.blkb	16.
pasbuf:	.blkb	16.
;
;
;	this routine is called by the executive whenever an io request is made
;	to the va driver.  The request is completed immediately.
;
;
vaini:
	mov	kisar6,-(sp)		; save current apr6 mapping
	mov	#err,status		; assume error
	clr	descript		; initialize descriptor
	mov	r1,r3			; IRP address needed in r3 for $iofin
	mov	i.tcb(r3),pcb		; store pcb address
	movb	i.fcn+1(r3),r0		; function code
	cmpb	r0,#io.wlb/256.		; send to aether?
	jeq	do_send			; YES
	cmpb	r0,#io.wvb/256.		; send to aether?
	jeq	do_send			; YES
	cmpb	r0,#io.rlb/256.		; receive next message?
	jeq	do_receive		; YES
	cmpb	r0,#io.rvb/256.		; receive next message?
	jeq	do_receive		; YES
	cmpb	r0,#io.cre/256.		; create an aether?
	jeq	do_create		; YES
	cmpb	r0,#io.acw/256.		; access an existing aether?
	jeq	do_access		; YES
	cmpb	r0,#io.dac/256.		; deaccess from aether?
	jeq	do_deaccess		; YES
	cmpb	r0,#io.cln/256.		; clean up after exiting task?
	jeq	do_clean		; YES
	cmpb	r0,#io.stp/256.		; stop timer for driver unload?
	jeq	do_stop			; YES
vafin:
	mov	status,r0		; return status
	mov	descript,r1		; second word in descript
	mov	(sp)+,kisar6		; restore apr6 mapping
	callr	$iofin			; finish up
#-h- doaccess.mac     258  asc  24-mar-81 08:49:32  [002,005]
	.page
	.sbttl	do_access - access an aether
do_access:
	jsr	pc,do_common		; perform common stuff
	bcs	10$			; c set => error
	jsr	pc,aet_access		; access aether
	tst	r0			; successful?
	beq	10$			; NO
	mov	#2,@i.ln2(r3)		; "file" open on lun
10$:
	jmp	vafin
#-h- doclean.mac      172  asc  24-mar-81 08:49:33  [002,005]
	.page
	.sbttl	do_clean - clean up after exiting process
do_clean:
	jsr	pc,aet_cleanup		; cleanup after exiting process
	clr	@i.ln2(r3)		; "file" no longer open
	jmp	vafin
#-h- docreate.mac     318  asc  24-mar-81 08:49:33  [002,005]
	.page
	.sbttl	do_create - create an aether
do_create:
	jsr	pc,do_common		; perform common stuff
	bcs	10$			; c set => error
	mov	i.p6(r3),if_access	; copy access if created switch
	jsr	pc,aet_create		; create the aether
	tst	r0			; successful?
	beq	10$			; NO
	mov	#2,@i.ln2(r3)		; "file" open on lun
10$:
	jmp	vafin
#-h- dodeacc.mac      179  asc  24-mar-81 08:49:34  [002,005]
	.page
	.sbttl	do_deaccess - deaccess from an aether
do_deaccess:
	mov	i.p1(r3),descript	; copy descriptor into global loc
	jsr	pc,aet_deaccess		; deaccess from aether
	jmp	vafin
#-h- doosend.mac      329  asc  24-mar-81 08:49:35  [002,005]
	.page
	.sbttl	do_osend - send message to aether owner
do_osend:
	mov	i.p1(r3),r0		; virtual address of name
	mov	aet_name,r4		; destination address
	jsr	pc,ackcpy		; address check and copy
	bcs	10$			; c set => error
	jsr	pc,setbuf		; set up buffer
	bcs	10$			; c set => error
	jsr	pc,aet_osend		; send to owner
10$:
	jmp	vafin
#-h- doreceive.mac    277  asc  24-mar-81 08:49:36  [002,005]
	.page
	.sbttl	do_receive - receive message from aether
do_receive:
	mov	#io.rlb/256.,r0		; convert rvb to rlb
	mov	i.p1(r3),descript	; user-supplied descriptor
	jsr	pc,setbuf		; set up buffer
	bcs	10$			; c set => error
	jsr	pc,aet_receive		; get next message
10$:
	jmp	vafin
#-h- dosend.mac       583  asc  24-mar-81 11:23:04  [002,005]
	.page
	.sbttl	do_send - send message to aether
do_send:
	mov	#normal,type		; assume normal message
	movb	i.fcn(r3),r1		; sub-function value
	beq	10$			; if 0, regular send
	cmpb	r1,#1			; send to owner?
	jeq	do_osend		; YES
10$:
	mov	i.p1(r3),descript	; user-supplied descriptor
	tst	r1			; regular send?
	beq	20$			; YES
	mov	#interrupt,type		; type of message
	jsr	pc,aet_isend		; send interrupt
	br	100$
20$:
	jsr	pc,setbuf		; set up user buffer
	bcs	100$			; c set => error
	mov	i.p4(r3),life_tim	; copy user-supplied life_time
	jsr	pc,aet_send		; send message
100$:
	jmp	vafin
#-h- dostop.mac       750  asc  24-mar-81 09:10:31  [002,005]
	.page
	.sbttl	do_stop - stop perpetual timer
do_stop:
	mov	#ie.pri&377,status	; assume error
	mov	i.tcb(r3),r0		; tcb address
	mov	t.ucb(r0),r0		; TI: UCB address
	bit	#u2.prv,u.cw2(r0)	; is terminal priveleged?
	beq	10$			; NO
	mov	u.clqb(r5),r0		; clock queue block
	beq	10$			; if 0, timer not active
	mov	r3,-(sp)		; save r3
	mov	r5,-(sp)		; save r5
	mov	#c.syst,r4		; clock queue request type
	mov	r0,r5			; id is block address
	jsr	pc,$clrsm		; remove entry from queue
	mov	(sp)+,r5		; restore UCB address
	mov	#c.lgth,r1		; length of block to return
	mov	u.clqb(r5),r0		; address of block
	jsr	pc,$deacb		; return block to DSR
	clr	u.clqb(r5)		; timer inactive
	mov	(sp)+,r3		; restore r3
	mov	#is.suc&377,status	; successful
10$:
	jmp	vafin
#-h- docommon.mac     794  asc  24-mar-81 08:49:38  [002,005]
	.page
	.sbttl	do_common - perform common stuff for create and access
;+
;	this routine copies the aether name, password, and interrupt
;	addresses into global locations
;
;	if any errors, returns c bit set, otherwise clear
;
;	r3, r5 remain the same across the call
;-
do_common:
	mov	i.p1(r3),r0		; virtual address of name
	mov	aet_name,r4		; address of name buffer
	jsr	pc,ackcpy		; address check and copy
	bcs	10$			; c set => error
	mov	i.p2(r3),r0		; virtual address of password
	mov	password,r4		; address of password buffer
	jsr	pc,ackcpy		; address check and copy
	bcs	10$			; c set => error
	mov	i.p3(r3),nml_ast	; copy normal ast address
	mov	i.p4(r3),int_ast	; copy interrupt ast address
	mov	i.p5(r3),ast_parm	; copy real ast address
	clc				; clear c bit for success
10$:
	return
#-h- ackcpy.mac       695  asc  01-apr-81 11:44:17  [002,005]
	.page
	.sbttl ackcpy - address check and copy small buffer
;
;	inputs
;		r0	virtual address of buffer
;		r4	destination to copy to
;	outputs
;		buffer will be address checked and copied
;		r0,r3,r5 unchanged
;		r1,r2,r4 mangled
;		c bit	set if error
;		c bit	clear if OK
;
ackcpy:
	mov	#16.,r1			; size of buffer
	jsr	pc,$achkb		; address check on byte boundaries
	bcs	30$			; c set => error
	jsr	pc,$reloc		; relocate relative to apr6
	mov	r1,kisar6		; load apr6
	mov	#7.,r1			; max bytes to move
10$:
	movb	(r2)+,(r4)+		; copy the character
	beq	20$			; if null, done
	sob	r1,10$			; try again
20$:
	clrb	(r4)			; make sure of null for strcmp's
	clc				; clear c bit for success
30$:
	return
#-h- setbuf.mac       584  asc  24-mar-81 11:23:07  [002,005]
	.page
	.sbttl	setbuf - set up user buffer
setbuf:
	mov	i.p3(r3),r1		; size of buffer
	blt	20$			; if < 0, error
	cmpb	r0,#io.rlb/256.		; read function
	beq	10$			; YES, any length is OK
	cmp	r1,u.cw4(r5)		; write too large?
	bgt	20$			; YES
10$:
	mov	r1,buf_size		; store in global variable
	mov	i.p2(r3),r0		; virtual address of buffer
	jsr	pc,$achkb		; check buffer addresses
	bcs	20$			; c set => error
	jsr	pc,$reloc		; relocate buffer
	mov	r1,kisar6		; load apr6
	mov	r2,buf_ptr		; apr6 virtual address
	clc				; c clear => success
	rts	pc
20$:
	sec				; c set => error
	rts	pc
#-h- vapwf.mac       2198  asc  24-mar-81 08:49:42  [002,005]
	.page
	.sbttl	vapwf - powerfail entry point
;+
;	this routine is called when the system is booted, upon restoration
;	of power, and when the driver is loaded, since the uc.pwf bit
;	is set in the u.ctl field of the UCB
;
;	this routine allocates a clock queue control block from pool
;	it then fills it in and queues it
;	the interrupt service routine propagates this interrupt.
;
;	this routine also places a pseudo-VCB address in U.VCB for
;	rundown in dreif
;
;	If the clock block cannot be allocated from pool, the driver indicates
;	that the device is offline by setting the bit in the u.st2 field
;	of the UCB and having TKTN issue a device not ready message on
;	the console.
;
;	inputs:
;		r3	controller index
;		r4	SCB address
;		r5	UCB address
;
;	outputs:
;	   1.	the delta time for each clock interrupt is calculated and
;		stored in the UCB
;	   2.	the address of the allocated clock block is stored in the UCB
;	   3.	a clock interrupt is queued for the driver
;
;-
	.enabl	lsb
vapwf:
	jsr	r0,__csav		; save registers
	mov	r5,(sp)			; save frame pointer
	mov	6(r5),r5		; UCB address in r5
	tst	u.clqb(r5)		; see if timer already active
	bne	20$			; if != 0, YES
	mov	r5,r0			; build "VCB" address
	add	#u.pvcb,r0		; now have "VCB" address
	mov	r0,u.vcb(r5)		; store it away in UCB
	mov	#tintpt,r0		; seconds between clock interrupts
	mov	$tkps,r1		; clock ticks/second
	jsr	pc,$mul			; double word delta time in r0,r1
	mov	r0,u.tim1(r5)		; save in UCB
	mov	r1,u.tim2(r5)
	mov	#c.lgth,r1		; size of clock queue core block
	jsr	pc,$alocb		; allocate from pool
	bcs	clkerr			; c set => allocation failure
	mov	r0,u.clqb(r5)		; save address of clock block
	mov	r5,c.ucb(r0)		; save UCB addr in clock block
	mov	#do_timer,c.sub(r0)	; address of interrupt service rtn
	mov	u.tim1(r5),r1		; delta time for $clins
	mov	u.tim2(r5),r2
	mov	#c.syst,r4		; clock queue request type
	mov	r0,r5			; clock queue id is block address
	jsr	pc,$clins		; insert into clock queue
	br	10$
clkerr:
	bisb	#us.ofl,u.st2(r5)	; set device offline
	mov	#t.ndnr,r0		; issue a device not ready
	jsr	pc,$dvmsg		; to console via TKTN
10$:
20$:
	mov	(sp),r5			; restore frame pointer
	jmp	__cret			; done
	.dsabl	lsb
#-h- dotimer.mac      456  asc  24-mar-81 08:49:43  [002,005]
	.page
	.sbttl	do_timer - perpetual timer
do_timer:
	jsr	r0,__csav		; save registers
	jsr	pc,aet_timer		; c version of timer
	mov	r5,(sp)			; save frame pointer
	mov	r4,r5			; id is clock block address
	mov	r5,r0			; address of block
	mov	c.ucb(r0),r4		; address of UCB
	mov	u.tim1(r4),r1		; time in ticks
	mov	u.tim2(r4),r2		; ...
	mov	#c.syst,r4		; system type
	jsr	pc,$clins		; insert into clock queue
	mov	(sp),r5			; restore frame pointer
	jmp	__cret
#-h- astrtns.mac     1639  asc  24-mar-81 08:58:14  [002,005]
	.page
	.sbttl	all_ast - allocate ast blocks
all_ast::
	jsr	r0,__csav		; save registers
	mov	12(r5),r4		; aether header address
	add	#10,r4			; point at first trailer
10$:
	mov	(r4),r4			; next trailer address
	beq	100$			; if == 0, done
	clr	14(r4)			; no AST block
	bit	12(r4),14(r5)		; message for this task?
	beq	10$			; NO
	mov	#c.lgth,r1		; size of block to allocate
	jsr	pc,$alocb		; allocate it from pool
	bcs	30$			; c set => failure
	mov	r0,14(r4)		; block address in trailer
	mov	r1,a.cbl(r0)		; size of AST block
	mov	#8.*2,a.byt(r0)		; byte allocation on task stack
	mov	10(r4),a.ast(r0)	; real ast address
	mov	#1,a.npr(r0)		; number of parameters
	mov	4(r4),a.prm(r0)		; assume normal ast
	tst	type			; is this true?
	beq	10$			; YES
	mov	6(r4),a.prm(r0)		; interrupt ast
	br	10$
30$:
	mov	12(r5),r4		; aether header address
	add	#10,r4			; point at first trailer
40$:
	mov	(r4),r4			; next trailer address
	beq	90$			; if == 0, done
	mov	14(r4),r0		; address of ast block
	beq	40$			; none
	mov	#c.lgth,r1		; size of block
	jsr	pc,$deacb		; return block to pool
	clr	14(r4)			; no block allocated
	br	40$
90$:
	mov	#err,r0			; return(ERR)
	br	110$
100$:
	mov	#ok,r0			; return(OK)
110$:
	jmp	__cret
	.page
	.sbttl	que_ast - queue software interrupts to processes
que_ast::
	jsr	r0,__csav		; save registers
	mov	12(r5),r4		; aether header address
	add	#10,r4			; point at first trailer
10$:
	mov	(r4),r4			; next trailer address
	beq	20$			; if == 0, done
	mov	14(r4),r1		; ast control block address
	beq	10$			; no ast for this task
	mov	2(r4),r0		; TCB address
	jsr	pc,$qastt		; queue ast to task
	br	10$
20$:
	jmp	__cret
#-h- vaend.mac        581  asc  01-apr-81 11:44:21  [002,005]
	.page
	.sbttl	free lists of headers, buffers and little buffers
bufsiz=32.
ltlsiz=14.
hdrsiz=12.
nbufs=60.
naets=20.
nltls=2*naets
nmsgs=nbufs/3
nhdrs=4*naets+nmsgs
;
	.macro	trmn8r	str,num
str'num=0
	.endm	trmn8r
	.macro	bldnod	str,size,num,nxt
str'num:
	.word	str'nxt
	.blkb	size
	.endm	bldnod
;
;
	trmn8r	hdr,\nhdrs
ctr=0
	.rept	nhdrs
	bldnod	hdr,hdrsiz,\ctr,\<ctr+1>
ctr=ctr+1
	.endr
;
;
	trmn8r	ltl,\nltls
ctr=0
	.rept	nltls
	bldnod	ltl,ltlsiz,\ctr,\<ctr+1>
ctr=ctr+1
	.endr
;
;
	trmn8r	buf,\nbufs
ctr=0
	.rept	nbufs
	bldnod	buf,bufsiz,\ctr,\<ctr+1>
ctr=ctr+1
	.endr
;
	.end
