mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-22 04:31:30 +00:00
748 lines
25 KiB
Plaintext
748 lines
25 KiB
Plaintext
|
;
|
|||
|
; File: BTALLOC.a
|
|||
|
;
|
|||
|
; Contains: These routines provide allocation of disk space for BTree files.
|
|||
|
; Space is allocated in node size units, a BTree node = n logical
|
|||
|
; blocks. Each node is identified by a node number which is the
|
|||
|
; logical block number (relative to the file space) of the first
|
|||
|
; block in the node.
|
|||
|
;
|
|||
|
; Written by: Bill Bruffey
|
|||
|
;
|
|||
|
; Copyright: © 1984-1991 by Apple Computer, Inc., all rights reserved.
|
|||
|
;
|
|||
|
; Change History (most recent first):
|
|||
|
;
|
|||
|
; <5> 9/10/91 JSM Cleanup header.
|
|||
|
; <4> 8/30/91 DTY Define onMac, onMacPP, and onHcMac to keep SonyEqu.a happy.
|
|||
|
; Defined to be 0 because this file is only used for the ROM
|
|||
|
; build, and we don’t build those ROMs any more. (onMac32 is the
|
|||
|
; base ROM.)
|
|||
|
; <3> 9/21/90 BG Removed <2>. 040s are behaving more reliably now.
|
|||
|
; <2> 6/20/90 CCH Added some NOPs for flaky 68040's.
|
|||
|
; <1.3> 6/12/89 JB Fixed UpdAltMDB to handle SuperDrive; vectored UpdAltMDB.
|
|||
|
; <1.2> 3/2/89 DNF removed references to forROM; HFS now builds identically for ram
|
|||
|
; or rom
|
|||
|
; <1.1> 11/10/88 CCH Fixed Header.
|
|||
|
; <1.0> 11/9/88 CCH Adding to EASE.
|
|||
|
; <•1.1> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
|
|||
|
; <1.0> 2/11/88 BBM Adding file for the first time into EASE…
|
|||
|
; 9/24/86 BB Modified to use new MPW equate files.
|
|||
|
; 1/8/86 BB Added UpdAltMDB subroutine and call to it in ExtBTFile (ROM75
|
|||
|
; Scavenger patch). ExtBTFile now sets CacheFlag = 'TRUE' to force
|
|||
|
; flushing following the extension of a BTree file.
|
|||
|
; 12/19/85 BB ExtBTFile now checks for errors returned from InitNode (not
|
|||
|
; patched in ROm75).
|
|||
|
; 10/25/85 BB Added jump vectors for ROM versions.
|
|||
|
; 10/17/85 BB Fixed ExtBtFile to force map record sizes to n long words.
|
|||
|
; 10/16/85 BB Fixed AllocNode to calculate the node numbers properly when
|
|||
|
; working with a bit map that has been extended. Fixed bug in
|
|||
|
; ExtBTFile which was subtracting the new map node from the free
|
|||
|
; count twice.
|
|||
|
; 10/10/85 BB Added use of new MOVEQ equates for GetBlock and RelBlock. Added
|
|||
|
; use of MarkBlock. Did some minor code clean up.
|
|||
|
; 9/25/85 BB Fixed bug in ExtBTFile which was moving a long instead of a byte
|
|||
|
; into the node type of a new map node.
|
|||
|
; 9/23/85 BB Removed check for null node pointer in RelMap, it is now checked
|
|||
|
; by RelNode.
|
|||
|
; 8/29/85 BB Modified ExtBTFile to accept a partial allocation.
|
|||
|
; 8/8/85 BB Modified ExtBTFile for new node format.
|
|||
|
; 6/10/85 BB Cleaned up some.
|
|||
|
; 3/15/85 BB Modified to use A6 stack.
|
|||
|
; 3/11/85 BB Added Extend BTree File (ExtBTFile).
|
|||
|
; 3/5/85 BB Added support for multiple map records.
|
|||
|
; 1/17/85 BB Removed use of BTree Global area (BTG).
|
|||
|
; 11/10/84 BB Added check for "no space".
|
|||
|
; 10/12/84 BB Modified to use file IO instead of physical disk IO. Modified to
|
|||
|
; use BTCB instead of VCB.
|
|||
|
; 9/30/84 BB Modified register usage and changed to use volume refnum instead
|
|||
|
; of drive number.
|
|||
|
; 8/21/84 BB New today
|
|||
|
;
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; External
|
|||
|
; Routines: AllocNode - Allocates a BTree disk node.
|
|||
|
; ExtBTFile - Extends a BTree file.
|
|||
|
; FreeNode - Frees(de-allocates) a Btree disk node.
|
|||
|
;
|
|||
|
; Internal
|
|||
|
; Subroutines: GetMap - Gets the next allocation map.
|
|||
|
; RelMap - Releases the node containing the current
|
|||
|
; allocation map.
|
|||
|
;
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
|
|||
|
if (&type('onMac') = 'UNDEFINED') then
|
|||
|
onMac: equ 0
|
|||
|
endif
|
|||
|
|
|||
|
if (&type('onMacPP') = 'UNDEFINED') then
|
|||
|
onMacPP: equ 0
|
|||
|
endif
|
|||
|
|
|||
|
if (&type('onHcMac') = 'UNDEFINED') then
|
|||
|
onHcMac: equ 0
|
|||
|
endif
|
|||
|
|
|||
|
BLANKS ON
|
|||
|
STRING ASIS
|
|||
|
|
|||
|
PRINT OFF
|
|||
|
LOAD 'StandardEqu.d'
|
|||
|
INCLUDE 'SonyEqu.a' ; for Sony format list equates
|
|||
|
PRINT ON
|
|||
|
PRINT NOGEN
|
|||
|
|
|||
|
|
|||
|
BTAlloc PROC EXPORT
|
|||
|
|
|||
|
EXPORT AllocNode,ExtBTFile,FreeNode
|
|||
|
|
|||
|
EXPORT vAllocNode,vExtBTFile,vFreeNode,vUpdAltMDB ; <1.3>
|
|||
|
|
|||
|
IMPORT GetNode,RelNode
|
|||
|
IMPORT GetRecA,InitNode
|
|||
|
IMPORT ExtendFile
|
|||
|
IMPORT MarkBlock
|
|||
|
IMPORT GetBlock,RelBlock ; <08Jan86>
|
|||
|
IMPORT FindDrive ; <08Jan86>
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: AllocNode
|
|||
|
;
|
|||
|
; Function: Allocates a BTree disk node.
|
|||
|
;
|
|||
|
; Input: A4.L - pointer to BTCB
|
|||
|
;
|
|||
|
; Output: D0.W - result code
|
|||
|
; D1.L - node number of allocated node
|
|||
|
;
|
|||
|
; Called by: BTInsert,SplitLT
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
AllocNode
|
|||
|
MOVE.L jAllocNode,-(SP) ; jumptable entry for vAllocNode <25Oct85>
|
|||
|
RTS ; go there <25Oct85>
|
|||
|
vAllocNode ; 'vectored' AllocNode routine <25Oct85>
|
|||
|
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D2-D4/A2-A3,-(A6) ; save registers <16Oct85>
|
|||
|
|
|||
|
MOVEQ #0,D4 ; beg node # for current map record <16Oct85>
|
|||
|
;
|
|||
|
; get next map record
|
|||
|
;
|
|||
|
SUBA.L A2,A2 ; start with map in header node
|
|||
|
ANGetMap
|
|||
|
BSR GetMap ; get next map record
|
|||
|
BEQ.S ANSearch ; ok ->
|
|||
|
CMPI.W #BTnotfound,D0 ; map node not found?
|
|||
|
BNE.S ANExit1 ; no, some other error ->
|
|||
|
MOVEQ #BTnospace,D0 ; result = "no space" <14Oct85>
|
|||
|
BRA.S ANExit1 ; exit ->
|
|||
|
;
|
|||
|
; search map record for a long word containing a free node (zero bit)
|
|||
|
;
|
|||
|
ANSearch
|
|||
|
MOVE.W D1,D2 ; map record size <16Oct85>
|
|||
|
LSR.W #2,D2 ; in long words <16Oct85>
|
|||
|
SUBQ.W #1,D2 ; - 1 = loop index <16Oct85>
|
|||
|
MOVEA.L A1,A0 ; start at beginning of the record
|
|||
|
@1 MOVE.L (A0)+,D0 ; next map long word
|
|||
|
CMPI.L #$FFFFFFFF,D0 ; any free blocks ?
|
|||
|
BNE.S ANFound ; ...yes, ->
|
|||
|
DBRA D2,@1 ; continue search <16Oct85>
|
|||
|
|
|||
|
EXT.L D1 ; map record size <16Oct85>
|
|||
|
LSL.L #3,D1 ; x 8 = # of nodes <16Oct85>
|
|||
|
ADD.L D1,D4 ; adjust beg node # <16Oct85>
|
|||
|
|
|||
|
BRA.S ANGetMap ; try next map record ->
|
|||
|
;
|
|||
|
; found a long word with some free blocks, locate 1st one
|
|||
|
;
|
|||
|
ANFound
|
|||
|
MOVE.W #31,D2 ; initial bit index
|
|||
|
@1 BTST D2,D0 ; free block?
|
|||
|
BEQ.S @2 ; ...yes ->
|
|||
|
DBRA D2,@1 ; try next bit
|
|||
|
@2 BSET D2,D0 ; mark block allocated
|
|||
|
|
|||
|
MOVE.L D0,D3 ; save updated map long word in D3
|
|||
|
LEA -4(A0),A0 ; position back to map long word
|
|||
|
MOVEA.L A0,A3 ; save ptr(map long word) in A3
|
|||
|
;
|
|||
|
; calculate node number for the selected node
|
|||
|
;
|
|||
|
SUBA.L A1,A0 ; byte offset to word
|
|||
|
MOVE.L A0,D1 ; put in D1
|
|||
|
LSL.L #3,D1 ; x 8 = bit offset to long word
|
|||
|
ADDI.L #31,D1 ; + bit offset within long word
|
|||
|
EXT.L D2 ;
|
|||
|
SUB.L D2,D1 ;
|
|||
|
ADD.L D4,D1 ; = node number <16Oct85>
|
|||
|
;
|
|||
|
; check for end of map
|
|||
|
;
|
|||
|
MOVE.L BTCNNodes(A4),D0 ; # of nodes = max node # + 1 <16Oct85>
|
|||
|
CMP.L D1,D0 ; target node within map range?
|
|||
|
BGT.S ANAlloc ; yes ->
|
|||
|
|
|||
|
BSR RelMap ; release map node
|
|||
|
MOVEQ #BTnospace,D0 ; result = "no space" <14Oct85>
|
|||
|
BRA.S ANExit1 ; exit ->
|
|||
|
;
|
|||
|
; allocate the node
|
|||
|
;
|
|||
|
ANAlloc
|
|||
|
MOVE.L D3,(A3) ; update the map
|
|||
|
|
|||
|
MOVEA.L A2,A0 ; mark the node dirty <10Oct85>
|
|||
|
JSR MarkBlock ; <10Oct85>
|
|||
|
|
|||
|
SUBQ.L #1,BTCFree(A4) ; adjust free block count
|
|||
|
BSET #BTCDirty,BTCFlags(A4) ; mark BTCB dirty
|
|||
|
|
|||
|
CLR.W D0 ; indicate no error
|
|||
|
;
|
|||
|
; clean up and exit
|
|||
|
;
|
|||
|
ANExit
|
|||
|
BSR RelMap ; release map node
|
|||
|
ANExit1
|
|||
|
MOVEM.L (A6)+,D2-D4/A2-A3 ; restore regs <16Oct85>
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set up condition codes
|
|||
|
RTS ; exit AllocNode
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: ExtBTFile
|
|||
|
;
|
|||
|
; Function: Extends a BTree file. The data fork of the BTree file is extended
|
|||
|
; by one clump-size unit. The file may be extended by less than one
|
|||
|
; clump if a full clump is not available. The BTree space map is
|
|||
|
; extended to include the additional file space.
|
|||
|
;
|
|||
|
; Input: A4.L - pointer to BTCB
|
|||
|
;
|
|||
|
; Output: D0.W - result code
|
|||
|
; 0 = ok
|
|||
|
; BTnospace = no available disk space
|
|||
|
; other = error
|
|||
|
;
|
|||
|
; Called by: BTInsert
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
ExtBTFile
|
|||
|
MOVE.L jExtBTFile,-(SP) ; jumptable entry for vExtBTFile <25Oct85>
|
|||
|
RTS ; go there <25Oct85>
|
|||
|
vExtBTFile ; 'vectored' ExtBTFile routine <25Oct85>
|
|||
|
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D2-D6/A2,-(A6) ; save registers
|
|||
|
;
|
|||
|
; extend the BTree file space (data fork)
|
|||
|
;
|
|||
|
MOVE.W BTCRefNum(A4),D1 ; file refnum
|
|||
|
MOVEA.L FCBSPtr,A1 ; A1 = ptr(1st FCB)
|
|||
|
MOVEA.L FCBVPtr(A1,D1.W),A2 ; A2 = ptr(VCB)
|
|||
|
MOVEQ #0,D3 ; no options <08Jan86>
|
|||
|
MOVE.L FCBClmpSize(A1,D1.W),D4 ; request one clump
|
|||
|
|
|||
|
JSR ExtendFile ; extend the file
|
|||
|
BEQ.S EFCalRange ; got the space -> <02Sep85>
|
|||
|
CMPI.W #DskFulErr,D0 ; 'disk full' error? <29Aug85>
|
|||
|
BNE EFExit1 ; no, some other error -> <29Aug85>
|
|||
|
TST.L D6 ; get any space? <29Aug85>
|
|||
|
BEQ EFExit1 ; no, give up -> <02Sep85>
|
|||
|
;
|
|||
|
; calculate node number range for new space
|
|||
|
;
|
|||
|
EFCalRange
|
|||
|
MOVE.L BTCNNodes(A4),D3 ; beg node # = current # of nodes <16Oct85>
|
|||
|
MOVE.L D3,D4 ; D3 and D4 = beg node #
|
|||
|
|
|||
|
MOVE.L FCBPLen(A1,D1.W),D5 ; get new physical length
|
|||
|
DIVU BTCNodeSize(A4),D5 ; physical length / node size
|
|||
|
SWAP D5 ; = number of nodes
|
|||
|
CLR.W D5 ;
|
|||
|
SWAP D5 ;
|
|||
|
MOVE.L D5,BTCNNodes(A4) ; update total number of nodes
|
|||
|
SUBQ.L #1,D5 ; # of nodes - 1 = node # of ending node
|
|||
|
MOVE.L D5,D6 ; D5 and D6 = end node #
|
|||
|
;
|
|||
|
; locate map positions for beginning and end of new space
|
|||
|
;
|
|||
|
SUBA.L A2,A2 ; start with map record in header
|
|||
|
EFGetMap
|
|||
|
BSR GetMap ; get next map record
|
|||
|
BNE EFExit1 ; error ->
|
|||
|
|
|||
|
EXT.L D1 ; map size(bytes)
|
|||
|
LSL.L #3,D1 ; x 8 = map size(bits)
|
|||
|
|
|||
|
SUB.L D1,D3 ; make relative begin/end node numbers
|
|||
|
SUB.L D1,D5 ; ...relative to next map record
|
|||
|
BGE.S @1 ; end node beyond this map ->
|
|||
|
|
|||
|
SUBQ.L #1,D4 ; adjust begin nodenum for no new map
|
|||
|
BRA.S EFUpdFree ; update free count ->
|
|||
|
|
|||
|
@1 TST.L NDFLink(A2) ; have another map node?
|
|||
|
BNE.S EFGetMap ; yes, continue search ->
|
|||
|
;
|
|||
|
; must extend the map, update the previous 'last' map node and release it
|
|||
|
;
|
|||
|
EFAddMap
|
|||
|
MOVE.L D4,NDFlink(A2) ; link new node to last node
|
|||
|
|
|||
|
TST.L D3 ; new space begin within last map record?
|
|||
|
BGE.S @1 ; no, must be all in new record ->
|
|||
|
|
|||
|
ADD.L D1,D3 ; make node number relative to this record
|
|||
|
DIVU #8,D3 ; div node number
|
|||
|
; CLR.L D0 ; by byte size <16Oct85>
|
|||
|
MOVE.W D3,D0 ; quotient = byte offset
|
|||
|
CLR.W D3
|
|||
|
SWAP D3 ; remainder = bit offset
|
|||
|
MOVEQ #7,D1 ; 7 - bit offset <16Oct85>
|
|||
|
SUB.L D3,D1 ; = bit index
|
|||
|
|
|||
|
BSET D1,0(A1,D0.W) ; pre-allocate map node <16Oct85>
|
|||
|
MOVEQ #-1,D3 ; indicate map node already allocated
|
|||
|
|
|||
|
@1 MOVEA.L A2,A0 ; mark the map node dirty <10Oct85>
|
|||
|
JSR MarkBlock ; <10Oct85>
|
|||
|
|
|||
|
BSR RelMap ; release the map node <10Oct85>
|
|||
|
BNE.S EFExit1 ; error -> <10Oct85>
|
|||
|
;
|
|||
|
; initialize a new map node
|
|||
|
;
|
|||
|
EFNewMap
|
|||
|
MOVE.L D4,D1 ; map node number = begin node number
|
|||
|
JSR InitNode ; get an initialized node
|
|||
|
BNE.S EFExit1 ; error -> <19Dec85>
|
|||
|
MOVE.L A0,A2 ; A2 = ptr(new map node)
|
|||
|
MOVE.B #NDMapNode,NDType(A2) ; set node type <25Sep85>
|
|||
|
MOVE.W #1,NDNRecs(A2) ; map is one large record
|
|||
|
|
|||
|
MOVE.W BTCNodeSize(A4),D1 ; D1 = node size <17Oct85>
|
|||
|
MOVEQ #-(lenND+4),D0 ; map rec size <17Oct85>
|
|||
|
ADD.W D1,D0 ; = nodesize - length(nd) - size(2 offsets) <17Oct85>
|
|||
|
LSR.W #2,D0 ; round down <17Oct85>
|
|||
|
LSL.W #2,D0 ; to long word <17Oct85>
|
|||
|
ADDI.W #lenND,D0 ; rec offset = map rec size + length(ND) <17Oct85>
|
|||
|
MOVE.W D0,-4(A2,D1.W) ; set free space offset <17Oct85>
|
|||
|
|
|||
|
; ADDQ.L #1,D4 ; don't include map node in free count <16Oct85>
|
|||
|
|
|||
|
TST.L D3 ; map node bit within new record?
|
|||
|
BLT.S @1 ; no -> <10Oct85>
|
|||
|
MOVE.B #$80,lenND(A2) ; pre-allocate 1st node (map node)
|
|||
|
|
|||
|
@1 MOVEA.L A2,A0 ; mark the map node dirty <10Oct85>
|
|||
|
JSR MarkBlock ; <10Oct85>
|
|||
|
;
|
|||
|
; update free node count
|
|||
|
;
|
|||
|
EFUpdFree
|
|||
|
SUB.L D4,D6 ; end node # - beg node # = # of nodes-1
|
|||
|
ADD.L D6,BTCFree(A4) ; adjust free node count
|
|||
|
BSET #BTCDirty,BTCFlags(A4) ; mark BTCB dirty
|
|||
|
;
|
|||
|
; clean up and exit
|
|||
|
;
|
|||
|
EFExit
|
|||
|
CLR.B D0 ; result = "ok"
|
|||
|
BSR RelMap ; release last map node
|
|||
|
ST CacheFlag ; flush cache after extension of B-Tree files <08Jan86>
|
|||
|
BSR UpdAltMDB ; update the alternate MDB <08Jan86>
|
|||
|
EFExit1
|
|||
|
MOVEM.L (A6)+,D2-D6/A2 ; restore regs
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set up condition codes
|
|||
|
RTS ; exit ExtBTFile
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: FreeNode
|
|||
|
;
|
|||
|
; Function: Frees (de-allocates) a Btree disk node.
|
|||
|
;
|
|||
|
; Input: D1.L - node number of node being released
|
|||
|
; A4.L - pointer to BTCB
|
|||
|
;
|
|||
|
; Output: D0.W - result code
|
|||
|
;
|
|||
|
; Called by: BTDelete
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
FreeNode
|
|||
|
MOVE.L jFreeNode,-(SP) ; jumptable entry for vFreeNode <25Oct85>
|
|||
|
RTS ; go there <25Oct85>
|
|||
|
vFreeNode ; 'vectored' FreeNode routine <25Oct85>
|
|||
|
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D2-D3/A2,-(A6) ; save registers
|
|||
|
MOVE.L D1,D3 ; D3 = input node number
|
|||
|
;
|
|||
|
; locate map record for target node
|
|||
|
;
|
|||
|
SUBA.L A2,A2 ; indicate no node buffer
|
|||
|
FNGetMap
|
|||
|
BSR.S GetMap ; get next map record
|
|||
|
BNE.S FNExit1 ; didn't find it ->
|
|||
|
|
|||
|
EXT.L D1 ; map size(bytes)
|
|||
|
LSL.L #3,D1 ; x 8 = map size(bits)
|
|||
|
SUB.L D1,D3 ; node within this record?
|
|||
|
BGE.S FNGetMap ; no, get next map record ->
|
|||
|
;
|
|||
|
; found map record, mark node free
|
|||
|
;
|
|||
|
FNFound
|
|||
|
ADD.L D1,D3 ; make node number relative to this rec
|
|||
|
DIVU #8,D3 ; div node number
|
|||
|
CLR.L D0 ; by byte size
|
|||
|
MOVE.W D3,D0 ; quotient = byte offset
|
|||
|
CLR.W D3
|
|||
|
SWAP D3 ; remainder = bit position
|
|||
|
MOVEQ #7,D1 ; 7 - bit position <16Oct85>
|
|||
|
SUB.L D3,D1 ; = bit index
|
|||
|
BCLR D1,0(A1,D0.W) ; mark node as free
|
|||
|
|
|||
|
MOVEA.L A2,A0 ; mark the map node dirty <10Oct85>
|
|||
|
JSR MarkBlock ; <10Oct85>
|
|||
|
|
|||
|
ADDQ.L #1,BTCFree(A4) ; adjust free count
|
|||
|
BSET #BTCDirty,BTCFlags(A4) ; mark BTCB dirty
|
|||
|
;
|
|||
|
; clean up and exit
|
|||
|
;
|
|||
|
FNExit
|
|||
|
CLR.B D0 ; indicate no error
|
|||
|
BSR.S RelMap ; release map node
|
|||
|
FNExit1
|
|||
|
MOVEM.L (A6)+,D2-D3/A2 ; restore regs
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set up condition codes
|
|||
|
RTS ; exit AllocNode/FreeNode
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;_________________________________________________________________________________
|
|||
|
;
|
|||
|
; Internal Subroutines
|
|||
|
;_________________________________________________________________________________
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Subroutine: GetMap
|
|||
|
;
|
|||
|
; Function: Gets next allocation map. If a current node buffer is not given,
|
|||
|
; the first map record (in the BTree header node) is obtained.
|
|||
|
;
|
|||
|
; Input: A2.L - ptr(node buffer) containing current map record
|
|||
|
; 0 = no current node buffer
|
|||
|
; A4.L - pointer to BTCB
|
|||
|
;
|
|||
|
; Output: D0.W - result code
|
|||
|
; 0 = ok
|
|||
|
; BTnotfound = map record not found (end of map)
|
|||
|
; other = error
|
|||
|
; A2.L - ptr(cache buffer) containing next map node
|
|||
|
; D2.L - node number of next map node
|
|||
|
; A1.L - ptr(map record) within map node
|
|||
|
; D1.W - size of map record (bytes)
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
GetMap
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
;
|
|||
|
; release current map node
|
|||
|
;
|
|||
|
MOVEQ #0,D2 ; assume map in header node <10Oct85>
|
|||
|
|
|||
|
MOVE.L A2,D0 ; have a current node?
|
|||
|
BEQ.S GMGetNode ; no, get header node ->
|
|||
|
MOVE.L NDFLink(A2),D2 ; get link to next map node
|
|||
|
|
|||
|
BSR.S RelMap ; release the current map node <10Oct85>
|
|||
|
BNE.S GMExit ; error -> <10Oct85>
|
|||
|
|
|||
|
TST.L D2 ; have a next node?
|
|||
|
BNE.S GMGetNode ; yes ->
|
|||
|
MOVEQ #BTnotfound,D0 ; result = 'map record not found' <14Oct85>
|
|||
|
BRA.S GMExit ; exit ->
|
|||
|
;
|
|||
|
; get next map node
|
|||
|
;
|
|||
|
GMGetNode
|
|||
|
MOVEQ #0,D1 ; no GetBlock options <10Oct85>
|
|||
|
JSR GetNode ; get map node
|
|||
|
BNE.S GMExit ; error ->
|
|||
|
MOVEA.L A0,A2 ; A2 = ptr(node buffer)
|
|||
|
;
|
|||
|
; locate map record and caculate its size
|
|||
|
;
|
|||
|
MOVEQ #0,D0 ; assume map record is record 0
|
|||
|
CMPI.B #NDHdrNode,NDType(A2) ; header node?
|
|||
|
BNE.S @1 ; no ->
|
|||
|
MOVEQ #2,D0 ; map record is record 2
|
|||
|
|
|||
|
@1 MOVEA.L A2,A1 ; locate
|
|||
|
JSR GetRecA ; ...the record
|
|||
|
MOVE.L A0,D1 ; D1 = ptr(record)
|
|||
|
MOVE.W NDNRecs(A2),D0 ; locate
|
|||
|
JSR GetRecA ; ...the last record in node
|
|||
|
MOVEA.L D1,A1 ; A1 = ptr(record)
|
|||
|
SUBA.L A1,A0 ; map size = ptr(last record)
|
|||
|
MOVE.W A0,D1 ; - ptr(map record)
|
|||
|
|
|||
|
CLR.W D0 ; result = ok
|
|||
|
GMExit
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set up condition codes
|
|||
|
RTS ; exit GetMap
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Subroutine: RelMap
|
|||
|
;
|
|||
|
; Function: Releases the node containing the current allocation map. The
|
|||
|
; node is released with no RelBlock options.
|
|||
|
;
|
|||
|
; Input: A2.L - pointer to current node buffer
|
|||
|
; 0 = no node buffer
|
|||
|
; A4.L - pointer to BTCB
|
|||
|
;
|
|||
|
; Output: D0.W - result code
|
|||
|
; 0 = ok
|
|||
|
; other = error
|
|||
|
; A2.L - set to zero (no map node)
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
RelMap
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D1/A0-A1,-(A6) ; save registers
|
|||
|
|
|||
|
MOVEQ #0,D1 ; no RelBlock options <10Oct85>
|
|||
|
MOVE.L A2,A0 ; ptr(node buffer) <23Sep85>
|
|||
|
JSR RelNode ; release the node
|
|||
|
|
|||
|
SUBA.L A2,A2 ; indicate no map node <10Oct85>
|
|||
|
|
|||
|
MOVEM.L (A6)+,D1/A0-A1 ; restore registers
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set up condition codes
|
|||
|
RTS ; exit RelMap
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Subroutine: UpdAltMDB
|
|||
|
;
|
|||
|
; Function: Updates the extent file or catalog file info retained in the alternate
|
|||
|
; MDB on disk. The updated info includes the PEOF and the MDB-resident
|
|||
|
; extent record (1st 3 extents) for the BTree file being extended. The
|
|||
|
; last-modified date (DrLsMod) is also updated.
|
|||
|
;
|
|||
|
; UpdAltMDB reads the Alternate MDB from disk ( via GetBlock), updates
|
|||
|
; the extent info, and writes the block back to disk (via RelBlock).
|
|||
|
; Note, the Alternate MDB block is left in the cache (not dirty). However,
|
|||
|
; it is re-read from disk the next time it is to be updated.
|
|||
|
;
|
|||
|
; Input: A4.L - pointer to BTCB
|
|||
|
;
|
|||
|
; Output: D0.W - result code
|
|||
|
; 0 = ok
|
|||
|
; other = error
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
UpdAltMDB
|
|||
|
move.l jUpdAltMDB,-(sp) ; enter routine through RAM vector...
|
|||
|
rts
|
|||
|
vUpdAltMDB
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D0-D2/A0-A3/A5,-(A6) ; save registers
|
|||
|
|
|||
|
MOVE.W BTCRefNum(A4),D1 ; D1 = file refnum
|
|||
|
MOVEA.L FCBSPtr,A5 ; A5 = ptr to FCB
|
|||
|
LEA 0(A5,D1.W),A5 ;
|
|||
|
MOVEA.L FCBVPtr(A5),A2 ; A2 = ptr to VCB
|
|||
|
|
|||
|
MOVE.W VCBDrvNum(A2),D2 ; drive number
|
|||
|
JSR FindDrive ; locate drive queue element (A3 = ptr to DQE)
|
|||
|
BNE uaExit ; no such drive, exit -> <1.3>
|
|||
|
;
|
|||
|
; Determine disk size. D2 is set to the disk size (in blocks). <1.3>
|
|||
|
;
|
|||
|
; Format List record returned by the SuperDrive version of the Sony Driver <1.3>
|
|||
|
;
|
|||
|
; One record per possible drive configuration is returned on a <1.3>
|
|||
|
; Status call with csCode = 6. The entry with bit 6 in flflags set <1.3>
|
|||
|
; is the 'current disk' configuration and is the entry used to <1.3>
|
|||
|
; determine drive size. <1.3>
|
|||
|
;
|
|||
|
FmtLstRec record 0 ; <1.3>
|
|||
|
frsize ds.l 1 ; Disk size in BYTES <1.3>
|
|||
|
frflags ds.b 1 ; flags <1.3>
|
|||
|
frspt ds.b 1 ; sectors per track <1.3>
|
|||
|
frtracks ds.w 1 ; total # of tracks <1.3>
|
|||
|
flrecsize equ * ; size of the format list record <1.3>
|
|||
|
endr
|
|||
|
|
|||
|
NFRecs equ 16 ; max # of FmtLstRec to allocate on the stack <1.3>
|
|||
|
|
|||
|
|
|||
|
IF (&TYPE('fmtLstCode') = 'UNDEFINED') THEN ; <1.3>
|
|||
|
fmtLstCode equ 6 ; <1.3>
|
|||
|
ENDIF ; <1.3>
|
|||
|
|
|||
|
WITH FmtLstRec ; <1.3>
|
|||
|
movem.l a0/a2/d0/d1,-(sp) ; Save what we use... <1.3>
|
|||
|
;
|
|||
|
; Try the Sony Driver control call to attempt to discover <1.3>
|
|||
|
; drive size. If it fails, revert to the old assumptions... <1.3>
|
|||
|
;
|
|||
|
sub.w #NFRecs*flrecsize,sp ; Make space for the format records <1.3>
|
|||
|
move.l sp,a2 ; Save format record buffer address <1.3>
|
|||
|
;
|
|||
|
; Push an ioparamblk on the stack <1.3>
|
|||
|
;
|
|||
|
moveq #(ioQElSize+1)/2-1,d0 ; <1.3>
|
|||
|
@1 clr.w -(sp) ; <1.3>
|
|||
|
dbf d0,@1 ; <1.3>
|
|||
|
move.l sp,a0 ; Parameter block address <1.3>
|
|||
|
|
|||
|
; Check here for Sony driver because 3rd party disk drivers don't <1.3>
|
|||
|
; correctly support _Status calls. Some don't even check the value <1.3>
|
|||
|
; of the CSCode parameter!!! For now, don't call any driver except <1.3>
|
|||
|
; our own Sony driver. Maybe someday we'll get all drivers to support <1.3>
|
|||
|
; the 'Format List' status call... <1.3>
|
|||
|
|
|||
|
moveq #0,d2 ; Vol size in 512-byte blocks if not a Sony <1.3>
|
|||
|
move.w dQDrvSz(a3),d2 ; <1.3>
|
|||
|
cmp.w #dskRfN,dQRefNum(a3) ; Is this a Sony drive? <1.3>
|
|||
|
bne.s ckVersn ; Skip Status call if not, check DQE version..<1.3>
|
|||
|
|
|||
|
move.w dQDrive(a3),ioVRefNum(a0) ; drive number <1.3>
|
|||
|
move.w dQRefNum(a3),ioRefNum(a0) ; driver refnum <1.3>
|
|||
|
move.w #fmtLstCode,csCode(a0) ; Opcode for 'Return Format List' <1.3> <1.3>
|
|||
|
|
|||
|
move.w #NFRecs,csParam(a0) ; max number of format records to return <1.3>
|
|||
|
move.l a2,csParam+2(a0) ; ptr to place to return format records <1.3>
|
|||
|
_Status ; Ask driver for drive sizes <1.3>
|
|||
|
bne.s guessiz ; If any error, guess the size... <1.3>
|
|||
|
;
|
|||
|
; Scan the returned list of format records for the entry which <1.3>
|
|||
|
; describes the 'current disk'. <1.3>
|
|||
|
;
|
|||
|
move.w csParam(a0),d0 ; Number of format entries returned <1.3>
|
|||
|
beq.s guessiz ; Go guess if driver returned zilch... <1.3>
|
|||
|
sub.w #1,d0 ; ...for DBF loop <1.3>
|
|||
|
@2
|
|||
|
btst #6,frflags(a2) ; Is this entry for the 'current disk' <1.3>
|
|||
|
bne.s @3 ; Xfer if so... <1.3>
|
|||
|
add.w #flrecsize,a2 ; Else, point to next record <1.3>
|
|||
|
dbf d0,@2 ; ...and try again <1.3>
|
|||
|
bra.s guessiz ; No 'current disk' found, go guess... <1.3>
|
|||
|
@3
|
|||
|
move.l frsize(a2),d2 ; Get drive size in BLOCKS <1.3>
|
|||
|
bra.s GVSzExit ; And return... <1.3>
|
|||
|
;
|
|||
|
; Attempt to determine the drive size by looking at the <1.3>
|
|||
|
; drive queue element. This method used for any driver not <1.3>
|
|||
|
; supporting the control call. <1.3>
|
|||
|
;
|
|||
|
guessiz
|
|||
|
move.w #800,d2 ; assume single-sided sony <1.3>
|
|||
|
tst.b dQDrvSz(a3) ; TwoSideFmt? <1.3>
|
|||
|
beq.s @1 ; br if not <1.3>
|
|||
|
add.l d2,d2 ; two-sided, double size <1.3>
|
|||
|
@1
|
|||
|
ckVersn
|
|||
|
tst.w qType(a3) ; new version element? <1.3>
|
|||
|
beq.s GVSzExit ; br if not <1.3>
|
|||
|
move.l dQDrvSz(a3),d2 ; it's a long in the new world <1.3>
|
|||
|
swap d2 ; but swapped for compatibility <1.3>
|
|||
|
GVSzExit
|
|||
|
add.w #ioQElSize+(NFRecs*flrecsize),sp ; Discard stuff on the stack <1.3>
|
|||
|
movem.l (sp)+,a0/a2/d0/d1 ; Restore scratch registers <1.3>
|
|||
|
ENDWITH ; <1.3>
|
|||
|
|
|||
|
;
|
|||
|
; Get the alternate MDB from disk.
|
|||
|
;
|
|||
|
uaGetMDB
|
|||
|
subq.l #2,d2 ; Convert disk size in blocks to alt MDB address
|
|||
|
MOVE.W VCBVRefNum(A2),D0 ; volume refnum
|
|||
|
MOVEQ #kGBRead,D1 ; force read option
|
|||
|
MOVEA.L BTCCQPtr(A4),A1 ; ptr to cache queue
|
|||
|
JSR GetBlock ; get the block (A0 = ptr to alt MDB)
|
|||
|
BNE.S uaExit ; error, exit ->
|
|||
|
|
|||
|
MOVEQ #kRBTrash,D1 ; set trash RelBlock option
|
|||
|
CMP.W #TSigWord,DrSigWord(A0) ; does it bear the Turbo signature?
|
|||
|
BNE.S uaRelBlk ; no, release the block and exit ->
|
|||
|
;
|
|||
|
; Update the extent info.
|
|||
|
;
|
|||
|
uaUpdate
|
|||
|
LEA DrCTFlSize(A0),A3 ; assume update for catalog
|
|||
|
MOVEQ #FSCTCNID,D0 ; catalog BTree file?
|
|||
|
CMP.L FCBFlNm(A5),D0 ;
|
|||
|
BEQ.S @1 ; yes ->
|
|||
|
MOVEQ #FSXTCNID,D0 ; extents BTree file?
|
|||
|
CMP.L FCBFlNm(A5),D0 ;
|
|||
|
BNE.S uaRelBlk ; no, release the block and exit ->
|
|||
|
LEA DrXTFlSize(A0),A3 ; point to extent file info
|
|||
|
|
|||
|
@1 MOVE.L FCBPlen(A5),(A3)+ ; update the file size (PEOF)
|
|||
|
|
|||
|
MOVEQ #(lenXDR/4)-1,D0 ; length of XDR (in long words) - 1
|
|||
|
LEA FCBExtRec(A5),A1 ; source = FCB extent record
|
|||
|
@2 MOVE.L (A1)+,(A3)+ ; update
|
|||
|
DBRA D0,@2 ; ...the extent record info
|
|||
|
|
|||
|
MOVE.L Time,DrLsMod(A0) ; update mod date also
|
|||
|
;
|
|||
|
; Release the block (with force write option).
|
|||
|
;
|
|||
|
MOVEQ #kRBWrite,D1 ; force write RelBlock option
|
|||
|
uaRelBlk
|
|||
|
JSR RelBlock ; release the block
|
|||
|
uaExit
|
|||
|
MOVEM.L (A6)+,D0-D2/A0-A3/A5 ; restore registers
|
|||
|
uaExit1
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set up condition codes
|
|||
|
RTS ; exit UpdAltMDB
|
|||
|
|
|||
|
END
|
|||
|
|