mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-22 19:31:02 +00:00
489 lines
19 KiB
Plaintext
489 lines
19 KiB
Plaintext
;
|
|
; File: MFSVOL.a
|
|
;
|
|
; Contains: This file contains MFS-specific volume-level routines.
|
|
;
|
|
; Copyright: © 1984-1991 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <2> 9/12/91 JSM Add a header.
|
|
; <1.1> 11/10/88 CCH Fixed Header.
|
|
; <1.0> 11/9/88 CCH Adding to EASE.
|
|
; <1.0> 2/11/88 BBM Adding file for the first time into EASE…
|
|
; 10/20/85 LAK Don't call MarkVCB if volume is locked. Fail to mount if a
|
|
; catalog-volume map inconsistency problem is found and the volume
|
|
; is locked (we can't fix the inconsistency).
|
|
; 10/14/85 PWD Changed Mountvol to rejoin common TFS thread of execution for
|
|
; remount check.
|
|
; 10/14/85 PWD Changed to rejoin common TFS thread of execution for remount
|
|
; check.
|
|
; 10/2/85 LAK Trash blocks in MountVol directory scan which have no entries so
|
|
; they don't displace more useful directory blocks.
|
|
; 10/1/85 LAK Changed to use TFS cache. MFSMount shares more code with TFS.
|
|
; Added loop detection for MFS mount consistency check.
|
|
; 10/1/85 LAK Changed to use TFS cache. MFSMount shares more code with TFS.
|
|
; Shrink VCB for MFS volumes to old size.
|
|
; 8/29/85 LAK Share actual eject code with TFS.
|
|
; 7/24/85 PWD Added code to transfer vital VCB info from new VCB on re-mount
|
|
; 7/23/85 PWD Changed disk recognition algorithm to use only SigWord, CrDate,
|
|
; and volume name.
|
|
; 7/12/85 PWD Changed to set up and maintain default WDCB and DefVRefNum
|
|
; 2/12/85 PWD Adapted from FS MountVol code
|
|
; 2/12/85 PWD Adapted from FSVol for use as adjunct to TFSVol. Transferred
|
|
; most internal routines, pruned entry code. Remainder is all
|
|
; MFS-specific, executed when TFSVol entry points detect an MFS
|
|
; volume.
|
|
; 1/25/85 LAK Uncommented above call for Mac.
|
|
; 1/25/85 LAK Uncommented status call in MountVol. Use EnQueue, DeQueue
|
|
; routines directly.
|
|
; 10/26/84 RFA Commented out Status call since Ron's driver doesn't support it
|
|
; 8/7/84 GSS New today.
|
|
; 8/7/84 GSS New today
|
|
;
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; External Routines: MFSMount,MFSUnMount
|
|
; GetVol,SetVol,FlushVol,GetVolInfo,Eject,Offline
|
|
;
|
|
; Internal Routines: MDspsBuf,MDspsMap
|
|
;
|
|
;_______________________________________________________________________
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: MFSMount
|
|
;
|
|
; Arguments: A2 (input) -- pointer to partially filled in VCB
|
|
; D0 (output) -- error code
|
|
; This call is executed synchronously after control is transferred
|
|
; here from MountVol.
|
|
;
|
|
; Calls: GetVCBDrv,GetVCBRfn,FindDrive,CmdDone,
|
|
; MyRead (via RdMstDirBlk)
|
|
;
|
|
; Function: Allocates memory for volume buffer and allocation map, and reads
|
|
; in the directory master block and block. The VCB is added to the
|
|
; VCB queue. (For remounts, VCB is not reallocated or requeued).
|
|
;
|
|
; Modification History:
|
|
;
|
|
; 07 Aug 84 GSS New today
|
|
; 26 Oct 84 RFA Commented out Status call since Ron's driver doesn't support it
|
|
; 25 Jan 85 LAK Uncommented above call for Mac.
|
|
; 12 Feb 85 PWD Adapted from FS MountVol code
|
|
; 12-Jul-85 PWD Changed to set up and maintain default WDCB and DefVRefNum
|
|
; 23-Jul-85 PWD Changed disk recognition algorithm to use only SigWord,
|
|
; CrDate, and volume name.
|
|
; 24-Jul-85 PWD Added code to transfer vital VCB info from new VCB on re-mount
|
|
; <01Oct85> LAK Changed to use TFS cache. MFSMount shares more code with TFS.
|
|
; Shrink VCB for MFS volumes to old size.
|
|
; <02Oct85> LAK Trash blocks in MountVol directory scan which have no entries
|
|
; so they don't displace more useful directory blocks.
|
|
; <14Oct85> PWD Changed to rejoin common TFS thread of execution for remount check.
|
|
;_______________________________________________________________________
|
|
|
|
MV_GetMFSMap
|
|
|
|
; Control is transferred here when MountVol encounters a disk whose MDB signature
|
|
; inidicates it's an MFS volume. By that time, memory for a VCB has already been
|
|
; allocated and filled in (DrvRefNum and DrvNum are valid, a VRefNum
|
|
; has been assigned). MFS master directory info has been transferred into VCB.
|
|
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
MOVEQ #MFSVCBLen,D0 ; shrink the VCB since our needs are <01Oct85>
|
|
MOVE.L A2,A0 ; more modest . . . <01Oct85>
|
|
_SetPtrSize ; <01Oct85>
|
|
|
|
MOVEQ #BtsPrBlk/4,D2 ; # bits per block in map table/4
|
|
MULU VCBNmBlks(A2),D2 ; compute number of bytes in table
|
|
ADDQ.L #1,D2 ; first add 1 to round up for odd blks
|
|
LSR.L #1,D2 ; #bytes=#bits/2 (D2 was # of bits/4)
|
|
MOVE.W D2,VCBMLen(A2) ; save in our volume structure
|
|
MOVEQ #MpTblStr,D7 ; index into directory block
|
|
|
|
MOVE.L D2,D0 ; request bytes
|
|
_NewPtr ,SYS ; get it
|
|
BNE MtVolEr1 ; exit if there's not enough memory (shared MFS/TFS exit)
|
|
MOVE.L A0,VCBMAdr(A2) ; put addr into VCB
|
|
MOVEQ #StrtDir,D3 ; current MDB disk block <01Oct85>
|
|
|
|
; at this point:
|
|
; A0 points to where map table starts
|
|
; A5 points to disk buffer
|
|
; D3 is current master directory disk block
|
|
; D2 is # bytes in map table
|
|
; D7 is index to map table in disk buffer
|
|
|
|
moveMapIn MOVE.W 0(A5,D7),(A0)+ ; move the map in.
|
|
ADDQ.W #2,D7 ; next word
|
|
SUBQ.W #2,D2 ; only move this many bytes
|
|
BLE.S mpTblIn ; br if table moved in
|
|
CMP.W #512,D7 ; have we moved this whole block?
|
|
BCS.S moveMapIn ; no, keep moving
|
|
|
|
; read next block of map in from disk--
|
|
|
|
ADDQ.W #1,D3
|
|
BSR MFSVolRead ; get next volume block
|
|
BNE.S MFSMtErr ; exit on master directory read errors
|
|
MOVEQ #0,D7 ; start at beginning of this block
|
|
BRA.S moveMapIn
|
|
|
|
; the map table is in, so verify it by comparing the number of free blocks
|
|
; against the value in the master directory block . . .
|
|
|
|
mpTblIn
|
|
BSR.S CkMFSMap ; see if map looks ok <01Oct85>
|
|
BEQ.S CkMFSVol ; br if so (check the catalog for consistency)
|
|
; exit if not (bad problem since VCB and map are
|
|
; flushed together)
|
|
MFSMDBErr MOVEQ #BadMDBErr,D0 ; report BadMDBErr to force 'disk damaged'
|
|
; message from format pack.
|
|
MFSMtErr BSR.S MDspsMap ; get rid of map storage <29Sep85>
|
|
BRA MtVolEr1 ; and share TFS cleanup for rest <29Sep85>
|
|
|
|
MDspsMap MOVEM.L D0/A0,-(SP) ; preserve all regs
|
|
MOVE.L VCBMAdr(A2),A0 ; return map table memory
|
|
_DisposPtr
|
|
CLR.L VCBMAdr(A2) ; (for MFSEject path)
|
|
MOVEM.L (SP)+,D0/A0 ; restore regs
|
|
RTS
|
|
|
|
; Check routine shared by Flush/Unmount
|
|
; Blows D1/D3/D5 - CCR set on result bt not D0
|
|
|
|
CkMFSMap: ; <01Oct85>
|
|
MOVEQ #2,D3 ; first alloc block is block 2
|
|
MOVEQ #0,D1 ; start with 0 free blocks
|
|
|
|
@1 BSR GtNxBlk
|
|
BNE.S @2 ; loop if unavailable
|
|
ADDQ.W #1,D1 ; one more available
|
|
@2 CMP.W VCBNmAlBlks(A2),D3
|
|
BHI.S @3 ; end if we looked at them all
|
|
ADDQ.W #1,D3 ; look at next block
|
|
BRA.S @1
|
|
|
|
@3 CMP.W VCBFreeBks(A2),D1 ; is the free block count as advertised?
|
|
RTS
|
|
|
|
; now make sure we are consistent with the number of files and next free
|
|
; file number by scanning the directory blocks
|
|
|
|
CkMFSVol:
|
|
MOVEQ #0,D1 ; number of entries
|
|
MOVEQ #0,D2 ; max used file number
|
|
MOVEQ #0,D7 ; inconsistency tab (->VCBAttrib+1)
|
|
BSR MFSRd1stDB ; get the first directory block
|
|
BNE.S MFSMtErr ; exit if we can't read the first one . . .
|
|
|
|
conChkLoop
|
|
TST.B FlFlags(A5) ; flags=0 means end of entries this blk <02Oct85>
|
|
BNE.S @0 ; br if any entries this block <02Oct85>
|
|
MOVE.L A5,A0 ; A0 has already been trashed <02Oct85>
|
|
EXG D1,D6 ; preserve D1 over call <02Oct85>
|
|
MOVEQ #kRBtrash,D1 ; rerelease this block trashed . . . <02Oct85>
|
|
JSR RelBlock ; to keep it from displacing more <02Oct85>
|
|
EXG D1,D6 ; important cache buffers <02Oct85>
|
|
|
|
@0 MOVEQ #0,D0 ; init index into directory block
|
|
|
|
@1 TST.B FlFlags(A5,D0) ; flags=0 means end of entries this blk
|
|
BEQ.S @3 ; br if no more entries this block
|
|
ADDQ.W #1,D1 ; incr number of files
|
|
CMP.L FlFlNum(A5,D0),D2 ; check the file number for this file
|
|
BHI.S @2 ; br if less than current max
|
|
MOVE.L FlFlNum(A5,D0),D2 ; otherwise it becomes the new max
|
|
|
|
@2 LEA FlStBlk(A5,D0),A3
|
|
BSR.S CkFilLen ; check file length against map table
|
|
BNE.S MFSMDBErr ; exit if loop detected . . . <01Oct85>
|
|
|
|
LEA FlRStBlk(A5,D0),A3
|
|
BSR.S CkFilLen ; and resource fork, too
|
|
BNE.S MFSMDBErr ; exit if loop detected . . . <01Oct85>
|
|
|
|
BSR GtNxEntry ; (A5,D0) point to next entry, D6 trashed
|
|
BCS.S @1 ; br if not finished with this block
|
|
|
|
@3 BSR MFSRdNxtDB ; get next directory block
|
|
BEQ.S conChkLoop
|
|
|
|
dScanDone CMP.W #DirFulErr,D0 ; was it really the end we reached?
|
|
BNE MFSMtErr ; exit if not . . .
|
|
|
|
CMP.L VCBNxtFNum(A2),D2 ; is VCB next file number greater?
|
|
BCS.S @1 ; br if so . . .
|
|
ADDQ.L #1,D2
|
|
MOVE.L D2,VCBNxtFNum(A2) ; otherwise, use next number
|
|
ADDQ.B #1,D7 ; bit 0 of attributes notes this problem
|
|
|
|
@1 CMP.W VCBNmFls(A2),D1 ; how about the file count?
|
|
BEQ.S @2
|
|
MOVE.W D1,VCBNmFls(A2) ; make it consistent
|
|
ADDQ.B #2,D7 ; bit 1 of attributes notes this problem
|
|
|
|
@2 TST.B D7 ; found any inconsistencies?
|
|
BEQ.S @5 ; If not, continue along our merry way
|
|
BSR CVFlgs ; Volume locked? <20Oct85>
|
|
BNE.S @5 ; Br if so. <20Oct85>
|
|
BSR MarkVCB ; Otherwise, set the VCB dirty
|
|
|
|
; now get the write protect status . . .
|
|
|
|
@5 OR.B D7,VCBAtrb+1(A2) ; add consistency status
|
|
BRA CheckRemount ; New VCB is ready: re-join TFS code to <14Oct85>
|
|
; check for remounts. <14Oct85>
|
|
|
|
; A short routine to follow the allocation thread of a file and check its PEOF/LEOF.
|
|
|
|
CkFilLen:
|
|
MOVEM.L D0-D6,-(SP) ; preserve all regs <20Oct85>
|
|
MOVE.W VCBNmAlBlks(A2),D1 ; maximum loop count <01Oct85>
|
|
MOVEQ #0,D6 ; will contain phys len of file via map
|
|
MOVE.L VCBAlBlkSiz(A2),D2 ; disk alloc block size
|
|
|
|
MOVE.W (A3),D3
|
|
BEQ.S @2 ; br if no start block
|
|
|
|
@1 BSR GtNxBlk
|
|
SUBQ #1,D1 ; decrement loop count.
|
|
BCS.S @6 ; exit with loop error if we hit -1
|
|
|
|
MOVE.W D5,D3 ; next block
|
|
BEQ.S @2 ; if it points to 0, don't count it
|
|
ADD.L D2,D6 ; otherwise, add an alloc block
|
|
CMP.W #$001,D3 ; last entry?
|
|
BNE.S @1 ; go again if not . . .
|
|
|
|
@2 MOVE.W (A3)+,D3 ; entry start block
|
|
MOVE.L (A3)+,D4 ; entry logical length
|
|
MOVE.L (A3)+,D5 ; entry physical length
|
|
CMP.L D5,D6 ; does entry info jive with map table?
|
|
BEQ.S @5 ; exit if so
|
|
|
|
MOVE.L D6,-(A3) ; otherwise, use the len from map table
|
|
BNE.S @3 ; br if length is non-zero
|
|
CLR.W D3 ; zero start blk if zero length
|
|
@3 CMP.L D6,D4 ; logical length greater than phys?
|
|
BLS.S @4 ; br if not
|
|
MOVE.L D6,D4 ; otherwise, pin it at the phys len
|
|
@4 MOVE.L D4,-(A3) ; adjusted logical length
|
|
MOVE.W D3,-(A3) ; and file start block
|
|
|
|
BSR CVFlgs ; Is the volume write-protected? <20Oct85>
|
|
BNE.S @6 ; exit if so (report MDB error) <20Oct85>
|
|
JSR MarkA5Block ; mark this block dirty <01Oct85>
|
|
BSET #2,D7 ; bit 2 notes we found a file length prob
|
|
|
|
@5 MOVEQ #0,D1 ; alles gut (set CCR) <01Oct85>
|
|
@6 MOVEM.L (SP)+,D0-D6 ; restore registers <20Oct85>
|
|
RTS ; exit with CCR set (BNE for loop error)
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: MFSFlush
|
|
; Arguments: A2 (input) -- VCB pointer to volume to flush
|
|
; D0 (output) -- error code
|
|
; Calls: FClose,MyWriteDB
|
|
; Called By: UnMountVol
|
|
; Function: All file buffers on the volume are flushed and any changed
|
|
; directory information is written out to the diskette.
|
|
;
|
|
; Modification History:
|
|
; 20 Nov 82 LAK Clears the modified bit after writing out the VCB.
|
|
; Removed logic to get rid of a file's own buffer after closing
|
|
; it (should be done by close routine; also changing open to
|
|
; get a pointer to a buffer from the user -> so user would
|
|
; deallocate after a close or an eject . . .
|
|
; Removed logic to deallocate the VCB buffers: this is now done
|
|
; by unmount volume . . .
|
|
; 06 Dec 82 LAK Modified for new file system data structures . . .
|
|
; 07 Dec 82 LAK Made into an external procedure.
|
|
; 21 Dec 82 LAK Changed to flush file buffers but not close the files; now
|
|
; combines code of both unmountvol and flushvol.
|
|
; 13 Jan 83 LAK Zeros rest of last block map block before writing it out;
|
|
; some cosmetic and minor changes. Fills in IODrvNum field.
|
|
; 26 Jan 83 LAK Doesn't read in the master block first anymore; always
|
|
; flushes dirty volume buffer.
|
|
; 02 Jun 83 LAK Made flush of off-line volume a no-op; also allows unmount
|
|
; of an off-line volume.
|
|
; 12 Feb 85 PWD Adapted from FSVol for use with TFSVol; left only MFS-specific
|
|
; code.
|
|
; <11Sep85> LAK Made into a routine.
|
|
;_______________________________________________________________________
|
|
|
|
MFSFlush
|
|
MOVE.L (SP)+,-(A6) ; Save return address for ,ASYNC calls <11Sep85>
|
|
MOVEM.L A0-A5/D1-D7,-(A6) ; Save all regs except D0 <11Sep85>
|
|
|
|
; All files on this volume are flushed now. See if volume's info should be
|
|
; updated. (map table, number of files)
|
|
|
|
TST.W VCBDrvNum(A2) ; is this volume off-line?
|
|
BEQ.S MFSFlDone ; then no need to flush
|
|
|
|
TST.B VCBFlags(A2) ; VCB dirty bit set?
|
|
BPL.S MFSFlCaches ; if not, just flush the caches . . . <01Oct85>
|
|
|
|
BSR CkMFSMap ; check map (blows D1,D3,D5) <01Oct85>
|
|
BNE.S MFSFlCaches ; don't write map if it looks bad <01Oct85>
|
|
|
|
MOVEQ #StrtDir,D3 ; start master block <01Oct85>
|
|
BSR MFSMapRead ; get a buffer w/o reading it <01Oct85>
|
|
BNE.S MFSFlExit ; exit on errors . . . <01Oct85>
|
|
JSR MarkA5Block ; mark it dirty now <01Oct85>
|
|
|
|
; We need to write out the block map and relevant VCB info: first
|
|
; transfer all directory info from VCB
|
|
|
|
MOVEQ #(VCBDILen/2)-1,D0 ; number of words to transfer
|
|
MOVE.L A5,A1 ; destination is the buffer
|
|
LEA VCBDInfoSt(A2),A0 ; source is VCB start of directory info
|
|
MOVE.L Time,VCBLsMod(A2) ; use time global var for mod time
|
|
|
|
@1 MOVE.W (A0)+,(A1)+ ; move it
|
|
DBRA D0,@1
|
|
|
|
; now write out the block map: first compute the number of bytes in the table
|
|
|
|
MOVE.L VCBMAdr(A2),A0 ; map address
|
|
MOVE.W VCBMLen(A2),D2 ; map length
|
|
MOVEQ #MpTblStr,D7 ; index into directory block
|
|
|
|
mvMpOut MOVE.W (A0)+,0(A5,D7) ; transfer into buffer area.
|
|
ADDQ.W #2,D7 ; next word
|
|
SUBQ.W #2,D2 ; count of how many to go
|
|
BLE.S mpTblOut ; all done.
|
|
CMP.W #512,D7 ; at end of disk block?
|
|
BCS.S mvMpOut ; if not, keep movin'
|
|
|
|
; write out this block before continuing with rest of map.
|
|
|
|
ADDQ.W #1,D3 ; next block for table
|
|
BSR MFSMapRead ; get a buffer w/o reading it <01Oct85>
|
|
BNE.S MFSFlExit ; exit on errors . . . <01Oct85>
|
|
JSR MarkA5Block ; mark it dirty now <01Oct85>
|
|
|
|
MOVEQ #0,D7 ; start at beginning of block
|
|
BRA.S MvMpOut ; move it out
|
|
|
|
; map is almost out. just need to write this last block (may be the only block)
|
|
|
|
mpTblOut
|
|
CMP.W #512,D7 ; at end of disk block?
|
|
BCC.S MFSFlCaches ; if so, write it out <01Oct85>
|
|
CLR.W 0(A5,D7) ; zero to the end of the block for looks
|
|
ADDQ.W #2,D7 ; next word
|
|
BRA.S mpTblOut ; if not, keep movin'
|
|
|
|
MFSFlCaches
|
|
BSR FlushBuffers ; flush all cache blks for this volume <01Oct85>
|
|
BNE.S MFSFlExit ; and trash them for unmount . . .
|
|
|
|
MFSFlDone
|
|
CLR.B VCBFlags(A2) ; VCB and block map are no longer dirty
|
|
TST.B FlushOnly ; only flushing?
|
|
BNE.S MFSFlOK ; br if so
|
|
|
|
; dispose the block map, VCB, and volume buffer memory
|
|
|
|
TST.W VCBDrvNum(A2) ; are we off-line?
|
|
BEQ.S @1 ; br if so (just deallocate VCB)
|
|
|
|
BSR MDspsMap ; dispose the block map memory
|
|
|
|
; For UnMountVol, dequeue the VCB and trash any WDCBs for this volume . . .
|
|
|
|
@1 BSR DsposVCB ; share code with MountVol error routine <29Sep85>
|
|
|
|
MFSFlOK MOVEQ #0,D0 ; it's cool <11Sep85>
|
|
MFSFlExit MOVEM.L (A6)+,A0-A5/D1-D7 ; Restore regs <11Sep85>
|
|
MOVE.L (A6)+,-(SP) ; Restore the return address <11Sep85>
|
|
TST.W D0 ; <11Sep85>
|
|
RTS ; <11Sep85>
|
|
|
|
;_______________________________________________________________________
|
|
;
|
|
; Routine: GetMFSVolInfo
|
|
; Arguments: A0.L (input) -- I/O volume parameter block: uses all volume
|
|
; fields.
|
|
; D0.W (output) -- error code
|
|
; Calls: FSQueue,CmdDone
|
|
;
|
|
; Function: Return information about the volume in a mounted drive.
|
|
; If the IOVolIndex field is 0,
|
|
; the name of the default volume is returned; if non-zero, the
|
|
; name of the nth mounted volume is returned. The maximum length
|
|
; of a volume name is 27 bytes. The drive number for the volume
|
|
; is also returned.
|
|
;
|
|
; Modification History:
|
|
; 07 Dec 82 LAK Changed to support new file system data structures.
|
|
; 16 Dec 82 LAK Removed backup file lgth subtract in free blk determination.
|
|
; 21 Dec 82 LAK Changed to call DtrmVol to figure the volume name. Free
|
|
; blocks comes from VCB info already stored.
|
|
; 14 Jan 83 LAK The latest changes.
|
|
; 23 Jan 83 LAK Changed to use the volindex field, call XferVName.
|
|
; 03 Jun 83 LAK Added in-use bit: true if any files on the volume are open;
|
|
; returns volume refnum now instead of drive number.
|
|
;
|
|
; - if this was the twin of GetFileInfo, the volume really shouldn't have to
|
|
; be mounted . . . if it is, get the info from the VCB and block map: if
|
|
; not, read the drive's master block into a stack buffer (would have to
|
|
; read the block map, tho, to determine the number of free blocks) . . .
|
|
;
|
|
; - set a bit somewhere if this volume is the default?
|
|
;_______________________________________________________________________
|
|
|
|
GetMFSVolInfo
|
|
BSR FSQueue ; queue up the request
|
|
|
|
MOVE.W IOVolIndex(A0),D2 ; if positive,
|
|
BGT.S @3 ; go search by index
|
|
BEQ.S @1 ; if zero, go by drive number/default
|
|
|
|
BSR DtrmV3 ; if negative, go by name
|
|
BRA.S @2
|
|
|
|
@1 BSR DtrmV1 ; figure by drvnum, vrefnum, or default
|
|
@2 BNE.S GMVIDone
|
|
BRA.S RetMFSVolInfo
|
|
|
|
@3 MOVE.L VCBQHdr+QHead,D1 ; we want nth VCB in queue
|
|
@4 BEQ NSVErrXit ; exit with err at end of queue
|
|
SUBQ.W #1,D2 ; the one we want?
|
|
MOVE.L D1,A2
|
|
BEQ.S RetMFSVolInfo ; br if so
|
|
MOVE.L QLink(A2),D1 ; if not, keep traversing the queue
|
|
BRA.S @4
|
|
|
|
; first copy the heart of the VCB into the parameter block
|
|
|
|
RetMFSVolInfo
|
|
BSET #6,VCBAtrb+1(A2) ; set if any files are opened
|
|
BSR.S Gt1stFCB ; get (A1,D1) pointing to first FCB
|
|
@1 CMP.L FCBVPtr(A1,D1),A2 ; file open on this volume?
|
|
BEQ.S @2 ; br if so
|
|
BSR.S GtNxtFCB ; get next one until we run out
|
|
BCS.S @1
|
|
BCLR #6,VCBAtrb+1(A2) ; 0 if no open files match
|
|
|
|
@2 MOVEQ #IOVDirLen-2,D0 ; number of bytes to straight copy
|
|
|
|
@3 MOVE.W VCBCrDate(A2,D0.W),IOVCrDate(A0,D0.W)
|
|
SUBQ #2,D0
|
|
BPL.S @3
|
|
|
|
; next, copy the name into the name buffer and get drive number
|
|
|
|
BSR XferVName
|
|
GMVIDone BRA CmdDone
|
|
|
|
|