 lib environment
 sttl Mount & Unmount Routines
 pag
 name mount
 global mount,unmnt,fabufs,umfdn

*
* mntset
*
* Find the block file name specified in ucname
* and verify that it is a block special device.
* Return 'eq' if error.
*

mntset lbsr tstsu is this super user?
 bne mntse5 if not, error
 ldb #1 set mem space
 lbsr pthnm find specd file
 cmpx #0 file found?
 beq mntse3 if not, error
 lda fmode,x get fdn mode
 bita #FSBLK is it block device?
 beq mntse2 if not, error
 ldd ffmap,x get device number
 pshs d save it
 lbsr frefdn free up the fdn
 clz set ret status
 puls d,pc return
mntse2 lbsr frefdn free the fdn
 lda #ENBLK set error
 bra mntse4
mntse3 lda #ENOFL set error
mntse4 sta uerror save error
mntse5 sez set ret status
 rts return


 pag

*
* mount
*
* System call to perform a mount.
*

mount bsr mntset set up mount device
 lbeq mount4 error?
 pshs d save device number
 ldd usarg1 get 2nd file name
 std ucname save it
 ldb #1 set mem space
 lbsr pthnm process the file name
 puls d reset device number
 cmpx #0 file found?
 lbeq open3 if not, error
 pshs d,x save params
 lda fmode,x get file mode
 bita #(FSBLK|FSCHR) is it a device?
 lbne mount6 if so, error
 ldd fnumbr,x check fdn number
 cmpd #1
 lbeq mount7 if mounting on a root
 lda frefct,x get file ref count
 deca only one ref?
 lbne mount6 if not, error
 ldd 0,s get device number
 lbsr mntslt find mount table slot
 beq mount6 any left?
 pshs u save mount entry
 ldd #$aaaa set temp sir entry
 std msir,u just to make entry busy
 std mdevic,u also set device
 ldd 2,s get device number
 lbsr dvopnb call devices open routine
 tst uerror any errors?
 lbne moun95
 ldd 2,s get dev number
 ldx #1 set root fdn number
 ldy #0 0 is hi part of block number
 lbsr rdbuf read in the sir
 tst uerror any errors?
 bne mount9
 ldd 2,s restore device #
 pshs x,y,u save registers
 ldx #2 read fdn 1 - the hard way
 ldy #0
 lbsr rdbuf
 tst uerror any I/O error
 bne 05f yes - error exit
 pshs y save buffer pointer
 leas -10,s temp space
 leax 0,s
 exg x,y
 ldu #0
 ldd #10
 lbsr cpybts
 leax 0,s point to FDN data
 lda fmode-fmode,x
 cmpa #FSDIR|FBUSY must be a directory
01 leas 10,s clean up temp space
 puls y restore buffer pointer
05 pshs cc save result
 lbsr freebf release I/O buffer
 puls cc restore result
 puls x,y,u restore registers
 beq 10f
 lda #EIO return I/O error if no good
 sta uerror
 bra mount9 error exit
10
* -- OK to mount
 puls u reset mount ptr
 ldd 0,s get dev number
 ldx 2,s point to fdn
 bsr mntsir set up new sir
 puls x,d reset args
 lda fstat,x get file status
 ora #FMNT show mounted on
 sta fstat,x save new status
 lbsr unlfdn unlock the fdn
mount4 rts return

mount6 lda #EBSY set busy error
moun65 sta uerror save it
 bra moun85

mount7 lda #EFLX "file exists" for mounting on a root
 bra moun65

mount8 ldd #0 zero mount entry
 std mdevic,u
 std msir,u
moun85 puls d,x clean up stack
 lbsr frefdn free the fdn
 rts return

mount9 jsr freebf free the buffer
 lda uerror save error status
 pshs a
 ldd 3,s close device
 lbsr fabufs flush buffers - can't use 'em anyway...
 jsr dvclsb
 puls a restore error status (from read)
 sta uerror
moun95 puls u reset stack
 bra mount8 finish error exit

 pag

*
* mntslt
*
* Find an entry in the mount table for a new
* mount.  Enter with the new device number
* in D.  If the device is already mounted, return
* a 'eq' status.
*

mntslt tfr d,x save dev number
 ldu #0 set null ptr
 ldy mtable point to mount table
 ldb smnt get mount count
 pshs b save count
 tfr x,d reset dev number
mntsl2 ldx msir,y get sir ptr
 beq mntsl4 is it null?
 cmpd mdevic,y is this the same device?
 beq mntsl6 if so, error
 bra mntsl5
mntsl4 cmpu #0 empty slot yet?
 bne mntsl5 if so, go ahead
 tfr y,u save mount slot
mntsl5 leay MSTSIZ,y find next mount entry
 dec 0,s dec the count
 bne mntsl2 repeat?
 puls b clean up stack
 cmpu #0 entry found?
 rts return
mntsl6 puls b getc ounter off stack
 sez set error status
 rts return


 pag

*
* mntsir
*
* Assign an sir table entry and install in the
* mount table.  On entry, u points to mount table,
* x points to fdn, d has device number, and y
* points to the buffer header containing the sir.
*

mntsir std mdevic,u set device in table
 stx mnodep,u set fdn pointer
 pshs u,y
 lbsr asnsir get an sir block
 tfr x,y
 stx msir,u save sir ptr in mnt slot
 ldx 0,s get buffer
 ldu #0 set 0 offset
 ldd #512 set xfr count
 lbsr cpybts copy sir data to mem
 puls y get buffer
 lbsr freebf free up the buffer
 puls x get mount entry
 ldy msir,x point to sir
 ldd #0
 std supdt,y clear out sir flags
 std slkfr,y and locks
 ldd usarg2 get write key
 andb #1 get low bit
 stb swprot,y save in sir
 rts return

*
* umfdn
*
* Unmount fdn check.  Check for the device in
* the busy fdn list.  The device is in d.
* Return 'eq' if error.
*

umfdn ldx #fdnbsy point to busy fdns
umfdn2 ldx ffwdl,x follow linked list
 beq umfdn4 end of list?
 cmpd fdevic,x unmount device?
 bne umfdn2 if not, ok
 lda #EBSY set error
 sta uerror save it
 sez set error status
 rts return
umfdn4 ldy #0
 ldx #fdnfre point to fdn free list
umfdn5 ldx ffwdl,x follow list links
 beq umfdn6 end of list?
 cmpd fdevic,x unmount devic?
 bne umfdn5
 sty fnumbr,x zero out fdn number
 bra umfdn5 repeat
umfdn6 clz set return status
 rts return

 pag

*
* unmnt
*
* Unmount system call.
*

unmnt lbsr update update all disk blocks
 lbsr mntset set up special file
 beq unmnt7 error?
 pshs d save device number
 ldx mtable point to mount table
 ldb smnt get mount count
 pshs b save count
 ldd 1,s get dev number
unmnt2 ldy msir,x get sir ptr
 beq unmnt3 is it null?
 cmpd mdevic,x is this the device?
 beq unmnt4
unmnt3 leax MSTSIZ,x move to next mount entry
 dec 0,s dec the count
 bne unmnt2 repeat?
 puls b clean up stack
 lda #ENMNT set error
 sta uerror (no mount found)
 puls d,pc return
unmnt4 leas 1,s clean up stack
 pshs x save mount entry
 bsr umfdn unmount the fdn
 beq unmnt6 error?
 ldy 0,s get mount entry
 ldy mnodep,y point to fdn
 lbsr lckfdn lock the fdn
 tfr y,x
 lda fstat,x get file status
 anda #!FMNT clear mount status
 sta fstat,x save new status
 lbsr frefdn free the fdn
 ldd 2,s get device number
 bsr fabufs go free all buffers associated with device
 jsr dvclsb close the device
 puls y get mount entry
 puls d get device
 ldx msir,y point to sir
 ldd #0
 std msir,y free mount entry
 lbra rlssir free the sir block
unmnt6 puls d,x clean up stack
unmnt7 rts return
 pag
*
* fabufs - free all buffers associated with a device
*  (D) - Device number
*
fabufs pshs d save device code
 lbsr flshd flush all device buffers
 ldd 0,s get device number
 ldx #blktab point to block dev table
 ldb #BLKSIZ find this guys entry
 mul
 leax d,x point to his entry in table
 ldx blktpt,x get device table
 pshs x save it
44 seti disable interrupts
45 ldx dtqfl,x get io q pointer
 beq 50f is q empty?
 ldd bfdvn,x check device number
 cmpd 2,s
 bne 45b if not for device being unmounted
 clri reenable interrupts
 ldb #BUFPR if not - wait for it to empty
 ldy #lbolt sleep for 4 seconds
 lbsr sleep
 ldx 0,s get device table pointer
 bra 44b repeat check
50 clri enable interrupts
 puls x get device table
 ldd 0,s get device number
 ldy dtdfl,x get 1st buffer in list
55 pshs y set up for compare
 cmpx 0,s++ end of buffer list?
 beq 58f
 cmpd bfdvn,y buffer for this device?
 bne 57f
 pshs a save dev number
 lda #$ff set bad minor dev number
 sta bfdvn+1,y set in buffer header
 puls a reset dn
57 ldy bfdfl,y get next buffer in list
 bra 55b repeat search
58 puls d,pc return
