#-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=ctr+1 .endr ; ; trmn8r ltl,\nltls ctr=0 .rept nltls bldnod ltl,ltlsiz,\ctr,\ ctr=ctr+1 .endr ; ; trmn8r buf,\nbufs ctr=0 .rept nbufs bldnod buf,bufsiz,\ctr,\ ctr=ctr+1 .endr ; .end