mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-24 07:31:22 +00:00
1348 lines
44 KiB
Plaintext
1348 lines
44 KiB
Plaintext
|
;
|
|||
|
; File: BTreeSvcs.a
|
|||
|
;
|
|||
|
; Contains: These routines provide service functions used to access
|
|||
|
; and maintain a BTree file.
|
|||
|
;
|
|||
|
; Modified for Sys7.0 B*tree Manager by Kenny SC. Tung
|
|||
|
;
|
|||
|
; Copyright: <09> 1984-1992 by Apple Computer, Inc., all rights reserved.
|
|||
|
;
|
|||
|
; Change History (most recent first):
|
|||
|
;
|
|||
|
; <SM1> 4/1/92 kc Changed the name prefex used to distinguish
|
|||
|
; routines used by the external B-Tree manager
|
|||
|
; from the versions used by the File System.
|
|||
|
; <09> Pre-SuperMario comments follow <20>
|
|||
|
; <13> 9/16/91 JSM Cleanup header.
|
|||
|
; <12> 2/21/91 KST dnf, #83596: Do not check for volume offline.
|
|||
|
; <11> 11/12/90 dnf include FileMgrPrivateEqu.a
|
|||
|
; <10> 9/27/90 KST Documentation changes only.
|
|||
|
; <9> 8/3/90 KST ExtBTFlush should't call FlushCache directly. It will call FS's <SM1>
|
|||
|
; flushfile only if D5 flag is set now.
|
|||
|
; <8> 4/11/90 KST Use ExtBTMaxDepth and related equates. <SM1>
|
|||
|
; <7> 4/5/90 KST make btDebug symbol default to 0.
|
|||
|
; <6> 4/4/90 KST BTInsert didn't check for MaxDepth limit and returns no error.
|
|||
|
; <5> 2/22/90 KST Documentation change and cleanup.
|
|||
|
; <4> 2/16/90 KST Take out debugger code.
|
|||
|
; <3> 2/16/90 KST Adding ExtGetUpdateHdr, ExtUpdateHdr routines for "RelMap" change.
|
|||
|
; <2> 2/12/90 KST Adding documentation for BTInsert using new buffer scheme.
|
|||
|
; 9/27/89 KSCT It used to use cache queue ptr from BTCCQptr(A4).now we pass
|
|||
|
; SysCtlCPtr in BTFlush. The code will run on 7.0 without
|
|||
|
; RamCAche.
|
|||
|
; 8/31/89 KSCT We can't mark block before Updating the leaf record because of
|
|||
|
; the new buffer scheme, not cache
|
|||
|
; 8/29/89 KSCT Fixed 2 bugs in BTSearch. It branches to the wrong label
|
|||
|
; (BSExit). This will causing a crash if the node hint is bad or
|
|||
|
; the node is bad.
|
|||
|
; 5/4/89 KSCT Fixed a bug in BTDelete, MOVE should be a long, not word.
|
|||
|
; 4/11/89 KSCT Fixing a serious bug that B*Tree grows without checking the
|
|||
|
; depth limit.
|
|||
|
; 9/25/86 BB Updated to use new MPW equate files.
|
|||
|
; 1/20/86 BB Fixed bug on CalBTVars, did not include space for a node pointer
|
|||
|
; in the index record size calculation (not patched in ROm75).
|
|||
|
; 12/18/85 BB BTInsert now checks for errors returned from ExtInitNode (not
|
|||
|
; patched in ROm75).
|
|||
|
; 11/20/85 BB Fixed update depth bug in BTDelete (ROM75 patch). Fixed ExtGetNode
|
|||
|
; error return bug in BTDelete (ROM75 patch).
|
|||
|
; 10/25/85 BB Added vectors for ROM versions.
|
|||
|
; 10/22/85 BB Moved BTClose, BTFlush, and BTOpen to ExtBTSvcs from BtIntf.
|
|||
|
; 10/21/85 BB Fixed bug in BTGetRecord which was trying to release a node it
|
|||
|
; didn't have after getting an IO error.
|
|||
|
; 10/14/85 BB Added use of new MOVEQ error equates.
|
|||
|
; 10/10/85 BB Fixed BTDelete and BtInsert to use MarkBlock instead of always
|
|||
|
; releasing nodes as "dirty". Added use of new MOVEQ equates for
|
|||
|
; GetBlock,RelBlock, and FlushCache. Did some minor code clean up.
|
|||
|
; 10/9/85 BB Fixed bug in calulation of the size of BTree variables.
|
|||
|
; 10/1/85 LAK Changed to .Include TFSEqu for cache, BTree equates.
|
|||
|
; 9/23/85 BB Modified BTDelete to call ExtClrNode for nodes being freed.
|
|||
|
; 9/23/85 BB Modified BTInsert to not check for a null node pointer before
|
|||
|
; calling ExtRelNode. ExtRelNode now checks for it.
|
|||
|
; 9/3/85 BB Fixed bug in Btdelete that was releasing parent nodes as dirty.
|
|||
|
; 8/29/85 BB Fixed bug in BTInsert that was releasing a node twice.
|
|||
|
; 8/9/85 BB Added code to maintain leaf record count and 1st and last node
|
|||
|
; numbers.
|
|||
|
; 8/6/85 BB Updated to use equates for index and leaf node types.
|
|||
|
; 7/10/85 BB Removed calls to BTFlush. This is now done by CM and FXM.
|
|||
|
; 7/8/85 BB Modified BTInsert and BTDelete to maintain links for index nodes
|
|||
|
; and to use the new ExtGetLtSib/ExtGetRtSib interface.
|
|||
|
; 6/10/85 BB Added BTSetUP and BTCleanup subroutines.
|
|||
|
; 6/5/85 BB Removed use of BTVars for temporary storage of data records.
|
|||
|
; 5/30/85 BB Modified BTGetRecord to set up default node and index markers
|
|||
|
; for BTree underflow/overflow conditions.
|
|||
|
; 5/24/85 BB Added call to BTFlush after an insert or delete.
|
|||
|
; 5/24/85 BB Modified all routines to selectively clear BTCB flags.
|
|||
|
; 4/21/85 BB Modified BTGetRecord to update current node and record index
|
|||
|
; marks after each successful call.
|
|||
|
; 3/15/85 BB Modified to use A6 stack.
|
|||
|
; 3/11/85 BB Added extend BTree file stuff.
|
|||
|
; 2/26/85 BB Finished adding hints.
|
|||
|
; 2/21/85 BB Added use of hints.
|
|||
|
; 2/18/85 BB Modified to support variable length keys in leaf nodes.
|
|||
|
; 2/12/85 BB Added save/restore for scratch registers
|
|||
|
; 1/17/85 BB Removed use of BTree Global area (BTG).
|
|||
|
; 1/5/85 BB Modified to return pointers to key and data record for BTSearch
|
|||
|
; and BTGetRecord. BTDelete also modified to no longer return
|
|||
|
; deleted record.
|
|||
|
; 1/1/85 BB Modified BTOpen to set up address of external key-compare
|
|||
|
; routine (currently "KeyCompare") in BTCB.
|
|||
|
; 10/10/84 BB Modified for BTree files.
|
|||
|
; 9/27/84 BB New today.
|
|||
|
;
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; External
|
|||
|
; Routines: BTClose - Closes a BTree file.
|
|||
|
; BTDelete - Deletes a record from a BTree file given the key.
|
|||
|
; BTFlush - Flushes a BTree file.
|
|||
|
; BTGetRecord - Gets the next/previous record from a BTree file.
|
|||
|
; BTInsert - Inserts a record into a BTree file given the key
|
|||
|
; and data record.
|
|||
|
; BTOpen - Opens a BTree file.
|
|||
|
; BTSearch - Searches a BTree file for a record given the key.
|
|||
|
; ExtBTUpdate - Marks the cache buffer containing the specified
|
|||
|
; BTree node as updated (dirty).
|
|||
|
; Internal
|
|||
|
; Subroutines: BTCleanUp - Cleans up after a BTree service call.
|
|||
|
; BTSetUp - Sets up for a BTree service call.
|
|||
|
; CalBTVars - Calculates the size of the BTree Variable storage
|
|||
|
; area (BTVars).
|
|||
|
;
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
BLANKS ON
|
|||
|
STRING ASIS
|
|||
|
|
|||
|
PRINT OFF
|
|||
|
LOAD 'StandardEqu.d'
|
|||
|
INCLUDE 'BtreeEqu.a'
|
|||
|
INCLUDE 'BtreePrivate.a' ; Use ExtBTMaxDepth <11Apr90><SM1>
|
|||
|
include 'FileMgrPrivate.a'
|
|||
|
PRINT ON
|
|||
|
PRINT NOGEN
|
|||
|
|
|||
|
IF &trim(&type('btDebug')) = 'UNDEFINED' THEN
|
|||
|
btDebug EQU 0
|
|||
|
ENDIF
|
|||
|
|
|||
|
ExtBTSvcs PROC EXPORT
|
|||
|
|
|||
|
EXPORT ExtBTClose,ExtBTDelete,ExtBTFlush,ExtBTGetRecord,ExtBTInsert,ExtBTSearch ;<SM1>
|
|||
|
EXPORT ExtBTUpdate
|
|||
|
Export ExtGetUpdateHdr, ExtUpdateHdr ; <16Feb90>
|
|||
|
|
|||
|
IMPORT ExtAllocNode,ExtExtBTFile,ExtFreeNode
|
|||
|
IMPORT ExtBuildIRec,ExtDeleteRec,ExtGetLtSib,ExtGetMaxkey,ExtGetRecA,ExtGetRtSib
|
|||
|
IMPORT ExtInitNode,ExtInsertRec,ExtLocRec,ExtLocTPR,ExtSearchNode
|
|||
|
IMPORT ExtUpdDRec,ExtUpdIKey, ExtLocBTCB
|
|||
|
IMPORT ExtRotateLt,ExtSplitLT,ExtTreeSearch
|
|||
|
IMPORT ExtClrNode,ExtGetNode,ExtRelNode
|
|||
|
IMPORT ExtMarkBlock, ExtWriteBlock, ExtDoAOCRWF ;<SM1>
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: BTClose
|
|||
|
;
|
|||
|
; Function: Closes a BTree file. The BTree Header (BTH) is updated and the
|
|||
|
; cache is flushed and trashed for the specified file. The BTCB
|
|||
|
; memory is also released.
|
|||
|
; Note: ExtBTFlush only flushes buffers to FS DiskCache not to disk. <SM1>
|
|||
|
; Input: D0.W - file refnum
|
|||
|
;
|
|||
|
; Output: D0.W - result code
|
|||
|
; 0 = ok
|
|||
|
; -n = IO error
|
|||
|
; 25Sep89 KSCT Don't call FlushCache, it is called in ExtBTFlush.
|
|||
|
;__________________________________________________________________________________
|
|||
|
ExtBTClose ;<SM1>
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D1-D5/A0-A4,-(A6) ; save regs
|
|||
|
MOVE.W D0,D3 ; D3 = file refnum
|
|||
|
MOVE.W D3,D0 ; locate the BTCB
|
|||
|
JSR ExtLocBTCB ;
|
|||
|
;
|
|||
|
; flush the BTCB and cache buffers for the file
|
|||
|
MOVEQ #0,D5 ; clear flag so that it will not flush fs cache
|
|||
|
JSR ExtBTFlush ; Flush everything first <SM1>
|
|||
|
BNE.S BCExit ; error ->
|
|||
|
|
|||
|
; release BTCB memory
|
|||
|
;
|
|||
|
@2 MOVEA.L A4,A0 ; release the BTCB
|
|||
|
_DisposPtr ;
|
|||
|
MOVEA.L FCBSPtr,A4 ; clear BTCB ptr
|
|||
|
CLR.L FCBBTCBptr(A4,D3.W) ; ... in FCB
|
|||
|
|
|||
|
CLR.W D0 ; result = 'ok'
|
|||
|
BCExit
|
|||
|
MOVEM.L (A6)+,D1-D5/A0-A4 ; restore regs
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set condition codes
|
|||
|
RTS ; exit BTClose
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: BTDelete
|
|||
|
;
|
|||
|
; Function: Deletes a record from a BTree file given the key.
|
|||
|
;
|
|||
|
; Input: A0.L - address of key
|
|||
|
; D0.W - file refnum
|
|||
|
;
|
|||
|
; Output: D0.W - result code
|
|||
|
; 0 = ok
|
|||
|
; BTnotfound = record not found
|
|||
|
; other = error
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
ExtBTDelete ;<SM1>
|
|||
|
; MOVE.L jBTDelete,-(SP) ; jumptable entry for vBTDelete <25Oct85>
|
|||
|
; RTS ; go there <25Oct85>
|
|||
|
;vBTDelete ; 'vectored' BTDelete routine <25Oct85>
|
|||
|
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D1-D5/A0-A4,-(A6) ; save regs
|
|||
|
;
|
|||
|
; initialize some things
|
|||
|
;
|
|||
|
BSR BTSetUp ; set up common stuff
|
|||
|
|
|||
|
CLR.L BTCNodeM(A4) ; invalidate current node mark
|
|||
|
|
|||
|
SUBA.L A2,A2 ; ...no left node buffer
|
|||
|
SUBA.L A3,A3 ; ...no right node buffer
|
|||
|
;
|
|||
|
; search tree for key
|
|||
|
;
|
|||
|
JSR ExtTreeSearch ; search for key
|
|||
|
MOVEA.L A1,A3 ; A3 = ptr(node buffer)
|
|||
|
BNE BDExit1 ; didn't find it ->
|
|||
|
MOVE.W D1,D5 ; D5 = record index
|
|||
|
;
|
|||
|
; delete record from node
|
|||
|
;
|
|||
|
BDDelete
|
|||
|
MOVEA.L A3,A1 ; ptr(node buffer)
|
|||
|
MOVE.W D5,D1 ; record index
|
|||
|
JSR ExtDeleteRec ; delete it
|
|||
|
|
|||
|
MOVEA.L A3,A0 ; ptr(node buffer) <10Oct85>
|
|||
|
JSR ExtMarkBlock ; mark it dirty <10Oct85> <SM1>
|
|||
|
|
|||
|
TST.W D5 ; delete 1st record ?
|
|||
|
BNE.S @1 ; no ->
|
|||
|
BSET #BTCKeyUpd,BTCFlags(A4) ; indicate key update required
|
|||
|
|
|||
|
@1 CMPI.B #NDLeafNode,NDType(A3) ; at leaf level?
|
|||
|
BNE.S BDRemove ; no ->
|
|||
|
SUB.L #1,BTCNRecs(A4) ; decrement number of leaf records
|
|||
|
|
|||
|
;
|
|||
|
; unlink the node if the last record was deleted
|
|||
|
;
|
|||
|
BDRemove
|
|||
|
TST.W NDNRecs(A3) ; node empty ?
|
|||
|
BGT.S BDNxtLev ; no ->
|
|||
|
|
|||
|
MOVEA.L A3,A0 ; ptr(node buffer)
|
|||
|
JSR ExtGetLtSib ; get left sibling node
|
|||
|
BNE BDExit1 ; error ->
|
|||
|
TST.L D1 ; is there a left sibling ?
|
|||
|
BEQ.S @1 ; no ->
|
|||
|
|
|||
|
MOVE.L NDFlink(A3),NDFlink(A1) ; update forward link
|
|||
|
MOVEQ #kRBdirty,D1 ; release <10Oct85>
|
|||
|
MOVEA.L A1,A0 ;
|
|||
|
JSR ExtRelNode ; ...left node buffer
|
|||
|
|
|||
|
@1 MOVEA.L A3,A0 ; ptr(node buffer)
|
|||
|
JSR ExtGetRtSib ; get right sibling node
|
|||
|
BNE BDExit1 ; error ->
|
|||
|
TST.L D1 ; is there a right sibling ?
|
|||
|
BEQ.S BDUpdPtrs ; no ->
|
|||
|
|
|||
|
MOVE.L NDBlink(A3),NDBlink(A1) ; update backward link
|
|||
|
MOVEQ #kRBdirty,D1 ; release <10Oct85>
|
|||
|
MOVEA.L A1,A0 ;
|
|||
|
JSR ExtRelNode ; ...right node buffer
|
|||
|
;
|
|||
|
; update 1st and last node pointers
|
|||
|
;
|
|||
|
BDUpdPtrs
|
|||
|
CMPI.B #NDLeafNode,NDType(A3) ; at leaf level?
|
|||
|
BNE.S BDFree ; no ->
|
|||
|
|
|||
|
TST.L NDBLink(A3) ; backward link = 0?
|
|||
|
BNE.S @1 ; no ->
|
|||
|
MOVE.L NDFlink(A3),BTCFNode(A4) ; yes, update 1st node number
|
|||
|
|
|||
|
@1 TST.L NDFLink(A3) ; forward link = 0?
|
|||
|
BNE.S BDFree ; no ->
|
|||
|
MOVE.L NDBlink(A3),BTCLNode(A4) ; yes, update last node number
|
|||
|
;
|
|||
|
; free the empty node
|
|||
|
;
|
|||
|
BDFree
|
|||
|
MOVEA.L A3,A0 ; clear the empty node <23Sep85>
|
|||
|
JSR ExtClrNode ; <23Sep85>
|
|||
|
|
|||
|
MOVEQ #kRBdirty,D1 ; release <10Oct85>
|
|||
|
JSR ExtRelNode ; ...node buffer
|
|||
|
SUBA.L A3,A3 ; indicate no buffer
|
|||
|
|
|||
|
MOVE.W BTCLevel(A4),D0 ; locate
|
|||
|
JSR ExtLocTPR ; ...TPR
|
|||
|
|
|||
|
MOVE.L TPRNodeN(A0),D1 ; free
|
|||
|
MOVE.W BTCRefNum(A4),D0 ;
|
|||
|
JSR ExtFreeNode ; ...the disk node
|
|||
|
|
|||
|
BSET #BTCDelIRec,BTCFlags(A4) ; indicate index record delete
|
|||
|
BCLR #BTCKeyUpd,BTCFlags(A4) ; ...and no key update
|
|||
|
;
|
|||
|
; move to next level
|
|||
|
;
|
|||
|
BDNxtLev
|
|||
|
SUB.W #1,BTCLevel(A4) ; bump to next level up
|
|||
|
BEQ.S BDRoot ; up to root level ->
|
|||
|
|
|||
|
BTST #BTCKeyUpd,BTCFlags(A4) ; key update required ? <03Sep85>
|
|||
|
BNE.S @1 ; yes -> <03Sep85>
|
|||
|
BTST #BTCDelIRec,BTCFlags(A4) ; index record delete required ? <03Sep85>
|
|||
|
BEQ BDExit ; no, all done -> <03Sep85>
|
|||
|
|
|||
|
@1 MOVE.W BTCLevel(A4),D0 ; locate TPR
|
|||
|
JSR ExtLocTPR ; for this level
|
|||
|
MOVE.W TPRRIndx(A0),D5 ; D5 = parent record index
|
|||
|
MOVE.L TPRNodeN(A0),D2 ; D2 = parent node number
|
|||
|
|
|||
|
MOVEQ #0,D1 ; get parent node <10Oct85>
|
|||
|
JSR ExtGetNode ;
|
|||
|
BNE BDExit1 ; error -> <20Nov85>
|
|||
|
MOVEA.L A0,A2 ; A2 = ptr(parent node buffer)
|
|||
|
;
|
|||
|
; update parent key
|
|||
|
;
|
|||
|
BDUpdKey
|
|||
|
BTST #BTCKeyUpd,BTCFlags(A4) ; key update required ?
|
|||
|
BEQ.S @1 ; no ->
|
|||
|
|
|||
|
MOVE.W D5,D0 ; locate
|
|||
|
MOVEA.L A2,A1 ;
|
|||
|
JSR ExtGetRecA ; ...parent index record
|
|||
|
MOVE.L A0,-(SP) ; ...and save it
|
|||
|
MOVE.L A3,A1 ; locate 1st key
|
|||
|
CLR.W D0 ;
|
|||
|
JSR ExtGetRecA ; ...in node
|
|||
|
MOVEA.L (SP)+,A1 ; ptr(parent index record)
|
|||
|
|
|||
|
JSR ExtUpdIKey ; update the key
|
|||
|
|
|||
|
MOVEA.L A2,A0 ; ptr(parent node buffer) <10Oct85>
|
|||
|
JSR ExtMarkBlock ; write it back <20Feb90><SM1>
|
|||
|
|
|||
|
TST.W D5 ; update to 1st key in node ?
|
|||
|
BEQ.S @1 ; yes, leave flag set ->
|
|||
|
BCLR #BTCKeyUpd,BTCFlags(A4) ; don't need to update next level
|
|||
|
|
|||
|
@1 MOVEQ #0,D1 ; release child <10Oct85>
|
|||
|
MOVE.L A3,A0 ;
|
|||
|
JSR ExtRelNode ; ...node buffer
|
|||
|
|
|||
|
MOVEA.L A2,A3 ; new child node = parent node
|
|||
|
MOVE.L D2,D3 ; should be a long, not word <5/4/89>
|
|||
|
;
|
|||
|
; check if done
|
|||
|
;
|
|||
|
BCLR #BTCDelIRec,BTCFlags(A4) ; indx rec delete required ? <03Sep85>
|
|||
|
BEQ.S @2 ; no ->
|
|||
|
BRA BDDelete ; delete parent index record ->
|
|||
|
|
|||
|
@2 BTST #BTCKeyUpd,BTCFlags(A4) ; another key update required ?
|
|||
|
BNE.S BDNxtLev ; yes ->
|
|||
|
BRA.S BDExit ; no, all done ->
|
|||
|
;
|
|||
|
; up to the root, check for an empty tree
|
|||
|
;
|
|||
|
BDRoot
|
|||
|
MOVE.L A3,D0 ; root node released?
|
|||
|
BNE.S BDUpdDepth ; no ->
|
|||
|
CLR.W BTCDepth(A4) ; set tree to empty state
|
|||
|
CLR.L BTCRoot(A4) ;
|
|||
|
BRA.S BDExit ; exit ->
|
|||
|
;
|
|||
|
; update tree depth
|
|||
|
;
|
|||
|
BDUpdDepth
|
|||
|
CMPI.W #1,NDNRecs(A3) ; check # of records left in root
|
|||
|
BGT.S BDExit ; > 1, all done ->
|
|||
|
TST.B NDType(A3) ; index node ?
|
|||
|
BNE.S BDExit ; no, all done ->
|
|||
|
|
|||
|
SUBQ.W #1,BTCDepth(A4) ; decrement tree depth
|
|||
|
|
|||
|
MOVEQ #0,D1 ; locate key and data for 1st record <10Oct85>
|
|||
|
MOVEA.L A3,A1 ;
|
|||
|
JSR ExtLocRec ; ... in node <10Oct85>
|
|||
|
MOVE.L (A1),BTCRoot(A4) ; new root = child node <10Oct85>
|
|||
|
;
|
|||
|
; release the previous root node
|
|||
|
;
|
|||
|
MOVEA.L A3,A0 ; clear the node buffer <23Sep85>
|
|||
|
JSR ExtClrNode ; <23Sep85>
|
|||
|
|
|||
|
MOVEQ #kRBdirty,D1 ; release the <10Oct85>
|
|||
|
JSR ExtRelNode ; ...node buffer
|
|||
|
SUBA.L A3,A3 ; indicate no buffer
|
|||
|
|
|||
|
MOVE.L D3,D1 ; free
|
|||
|
MOVE.W BTCRefNum(A4),D0 ;
|
|||
|
JSR ExtFreeNode ; ...the node
|
|||
|
; <20Nov85>
|
|||
|
; get new root node and check if depth can be reduced again <20Nov85>
|
|||
|
; <20Nov85>
|
|||
|
MOVE.L BTCRoot(A4),D3 ; D3 = new root node # <20Nov85>
|
|||
|
MOVE.L D3,D2 ; get the new root node <20Nov85>
|
|||
|
MOVEQ #0,D1 ; <20Nov85>
|
|||
|
JSR ExtGetNode ; <20Nov85>
|
|||
|
BNE.S BDExit1 ; error -> <20Nov85>
|
|||
|
|
|||
|
MOVEA.L A0,A3 ; A3 = ptr to node buffer <20Nov85>
|
|||
|
BRA.S BDUpdDepth ; check out new root -> <20Nov85>
|
|||
|
|
|||
|
;
|
|||
|
; release last node and exit
|
|||
|
;
|
|||
|
BDExit
|
|||
|
BSET #BTCDirty,BTCFlags(A4) ; mark BTCB dirty
|
|||
|
CLR.W D0 ; result = ok
|
|||
|
BDExit1
|
|||
|
MOVE.W D0,-(A6) ; save result code
|
|||
|
|
|||
|
MOVEA.L A3,A0 ; ptr(node buffer) <23Sep85>
|
|||
|
MOVEQ #0,D1 ; <10Oct85>
|
|||
|
JSR ExtRelNode ; release it
|
|||
|
|
|||
|
MOVE.W (A6)+,D0 ; restore result code
|
|||
|
|
|||
|
BSR BTCleanUP ; clean up
|
|||
|
|
|||
|
MOVEM.L (A6)+,D1-D5/A0-A4 ; restore regs <29Aug85>
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set condition codes
|
|||
|
RTS ; exit BTDelete
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: BTFlush
|
|||
|
;
|
|||
|
; Function: Flushes a BTree file. The BTree Header (BTH) is updated and the
|
|||
|
; cache is flushed for the specified file.
|
|||
|
;
|
|||
|
; Input: D0.W - file refnum
|
|||
|
; A4.L - BTCB
|
|||
|
; D5.B - Write flag, If set then flush file system cache.
|
|||
|
; Output: D0.W - result code
|
|||
|
; 0 = ok
|
|||
|
; -n = IO error
|
|||
|
; 30Jul90 KST Flush B*Tree private cache buffers for the specific file.
|
|||
|
; Only call FlushCache if D5 flag is set.
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
ExtBTFlush ; 'vectored' BTFlush routine <25Oct85><SM1>
|
|||
|
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D1-D4/A0-A4,-(A6) ; save regs
|
|||
|
MOVE.W D0,D3 ; D3 = file refnum
|
|||
|
MOVEA.L FCBsPtr,A1 ; point into FCB array
|
|||
|
MOVEA.L FCBVPtr(A1,D3.W),A2; point to VCB
|
|||
|
|
|||
|
; we have the BTCB already
|
|||
|
; JSR ExtLocBTCB ; locate the BTCB
|
|||
|
BCLR #BTCdirty,BTCFlags(A4) ; is the BTCB dirty?
|
|||
|
BEQ.S BFFlush ; no, just flush cache ->
|
|||
|
|
|||
|
BSR.S ExtGetUpdateHdr ; get BTH from disk in A3 and update it
|
|||
|
BNE.S BFExit ; can't get it <2/16/90>
|
|||
|
; release cache buffer
|
|||
|
MOVEQ #kRBdirty,D1 ; release 'dirty' <14Oct85>
|
|||
|
MOVEA.L A3,A0 ; cache buffer ptr
|
|||
|
JSR ExtRelNode ; release it
|
|||
|
BNE.S BFExit ; error ->
|
|||
|
;
|
|||
|
; flush the private cache buffers for the B*Tree manager, don't call FlushCache.
|
|||
|
; Note: this is a delayed write if D5 is not set. <01Aug90>
|
|||
|
BFFlush
|
|||
|
MOVEA.L BTCCQptr(A4),A3 ; ptr to cache queue <30Jul90>
|
|||
|
MOVE.W btQBSize(A3),D4 ; D4=INIT B*Tree buffer size <30Jul90>
|
|||
|
LEA btQBStart(A3),A3 ; A3=first buffer <30Jul90>
|
|||
|
MOVEQ #btBufferN,D1 ; number of private buffers <30Jul90>
|
|||
|
SUBQ #1,D1 ; for dbring <30Jul90>
|
|||
|
@flushLoop
|
|||
|
CMP.W btBHRefNum(A3),D3 ; same file? <30Jul90>
|
|||
|
BNE.S @4 ; no <30Jul90>
|
|||
|
BCLR #CBHdirty,btBHFlags(A3) ; buffer dirty? <30Jul90>
|
|||
|
BEQ.S @4 ; no <30Jul90>
|
|||
|
;; buffer dirty, so write it to FS, A4 trashed here. <30Jul90>
|
|||
|
MOVEA.L A3,A4 ; A4 = ptr(buffer header) <30Jul90>
|
|||
|
JSR ExtWriteBlock ; write block to FS <30Jul90>
|
|||
|
|
|||
|
@4 ADDA.W D4,A3 ; next buffer <30Jul90>
|
|||
|
ADDA.W #lenBTBH,A3 ; ... and skip header <30Jul90>
|
|||
|
DBRA D1,@flushLoop ; continue <30Jul90>
|
|||
|
|
|||
|
TST.B D5 ; flush fs cache? <01Aug90>
|
|||
|
BEQ.S @BFRet ; no, all done <01Aug90>
|
|||
|
;; here, call file system's flushcache <01Aug90>
|
|||
|
MOVEa.L FSVarsPtr,A1 ; <01Aug90>
|
|||
|
MOVEA.L fsVars.btMgr(A1),A1 ; <01Aug90>
|
|||
|
MOVEA.L btVParam(A1),A0 ; A0 = BT Param <01Aug90>
|
|||
|
MOVE.W D3,ioRefNum(A0) ; file refnum <01Aug90>
|
|||
|
MOVEQ #DoFlushFile,D1 ; indicate this is FlushFile <01Aug90>
|
|||
|
BSR ExtDoAOCRWF ; flush cache <01Aug90>
|
|||
|
BNE.S BFExit ; error <01Aug90>
|
|||
|
|
|||
|
@BFRet MOVEQ #0,D0 ; no error <01Aug90>
|
|||
|
; clean up and exit
|
|||
|
;
|
|||
|
BFExit
|
|||
|
MOVEM.L (A6)+,D1-D4/A0-A4 ; restore regs
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set condition codes
|
|||
|
RTS ; exit BTFlush
|
|||
|
|
|||
|
; __________________________________________________________________________
|
|||
|
; Function: get BTH from disk and update it from BTCB info
|
|||
|
; Input: A4.L - BTCB <2/16/90>
|
|||
|
; Output: D0=0 if read header and then A3.L = header buffer ptr
|
|||
|
; Trashes: D0, D1, D2, A0, A1, A3
|
|||
|
; __________________________________________________________________________
|
|||
|
ExtGetUpdateHdr
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEQ #0,D1 ; no options
|
|||
|
MOVEQ #0,D2 ; BTH is disk block 0
|
|||
|
JSR ExtGetNode ; get disk block
|
|||
|
BNE.S @6 ; couldn't get it ->
|
|||
|
MOVEA.L A0,A3 ; A3 = cache buffer ptr
|
|||
|
BSR.S ExtUpdateHdr
|
|||
|
|
|||
|
@6 MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set condition codes
|
|||
|
RTS ; exit BTFlush
|
|||
|
; __________________________________________________________________________
|
|||
|
; Function: update BTH from BTCB info. This routine is SYNC.
|
|||
|
; Input: A4.L = BTCB, A3.L = header buffer ptr.
|
|||
|
; Output: D0=0 <2/16/90>
|
|||
|
; Trashes: D0, A0, A1
|
|||
|
; __________________________________________________________________________
|
|||
|
ExtUpdateHdr
|
|||
|
MOVE.W #LenMemBTH-1,D0 ; loop index
|
|||
|
LEA BTCDepth(A4),A0 ; ptr(source)
|
|||
|
LEA lenND(A3),A1 ; ptr(destination)
|
|||
|
@4 MOVE.B (A0)+,(A1)+ ; move it
|
|||
|
DBRA D0,@4 ; ...in
|
|||
|
|
|||
|
MOVEQ #0,D0
|
|||
|
RTS
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: BTGetRecord
|
|||
|
;
|
|||
|
; Function: Gets a record from a BTree file. Any previous, current,
|
|||
|
; or next record relative to the last BTSearch or BTGetRecord
|
|||
|
; operation may be obtained.
|
|||
|
;
|
|||
|
; Input: D0.W - refnum
|
|||
|
; D1.W - selection code
|
|||
|
; -n = previous record
|
|||
|
; 0 = current record
|
|||
|
; +n = next record
|
|||
|
;
|
|||
|
; Output: D0.W - result code
|
|||
|
; 0 = ok
|
|||
|
; BTnotfound = record not found
|
|||
|
; other = error
|
|||
|
; A0.L - pointer to key
|
|||
|
; A1.L - pointer to data record
|
|||
|
; D1.W - size of data record
|
|||
|
; D2.L - BTree hint
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
ExtBTGetRecord ;
|
|||
|
; MOVE.L jBTGetRecord,-(SP) ; jumptable entry for vBTGetRecord <25Oct85>
|
|||
|
; RTS ; go there <25Oct85>
|
|||
|
;vBTGetRecord ; 'vectored' BTGetRecord routine <25Oct85>
|
|||
|
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D3-D5/A2-A4,-(A6) ; save regs
|
|||
|
;
|
|||
|
; initialize some things
|
|||
|
;
|
|||
|
BSR BTSetUp ; set up common stuff
|
|||
|
|
|||
|
MOVE.W D1,D5 ; D5 = selection code
|
|||
|
SUBA.L A3,A3 ; indicate no node buffer
|
|||
|
;
|
|||
|
; set up starting position in BTree
|
|||
|
;
|
|||
|
MOVE.W BTCIndexM(A4),D4 ; current index mark
|
|||
|
MOVE.L BTCNodeM(A4),D3 ; current node mark
|
|||
|
BNE.S @1 ; valid node number ->
|
|||
|
MOVEQ #BTnotfound,D0 ; set return code <14Oct85>
|
|||
|
BRA.S GRExit1 ; exit ->
|
|||
|
@1 ADD.W D5,D4 ; adjust index
|
|||
|
;
|
|||
|
; locate the record relative to the starting position
|
|||
|
;
|
|||
|
GRLocate
|
|||
|
BSR.S GRGetNode ; get the node
|
|||
|
BNE.S GRExit1 ; error ->
|
|||
|
|
|||
|
@1 TST.W D4 ; check index bounds
|
|||
|
BLT.S @3 ; < 0, get previous node ->
|
|||
|
MOVE.W NDNRecs(A3),D1 ;
|
|||
|
CMP.W D1,D4 ;
|
|||
|
BLT.S GRGotIt ; < #recs, got it ->
|
|||
|
|
|||
|
MOVE.L NDFlink(A3),D0 ; get next node number
|
|||
|
BEQ.S @2 ; don't have one ->
|
|||
|
MOVE.L D0,D3 ; D3 = next node number
|
|||
|
SUB.W D1,D4 ; adjust index
|
|||
|
BRA.S GRLocate ; try next node
|
|||
|
|
|||
|
@2 MOVE.W D1,D4 ; new index mark = index of last record
|
|||
|
SUBQ.W #1,D4 ;
|
|||
|
BRA.S @5 ; use common exit ->
|
|||
|
|
|||
|
@3 MOVE.L NDBlink(A3),D0 ; get previous node number
|
|||
|
BEQ.S @4 ; don't have one ->
|
|||
|
MOVE.L D0,D3 ; D3 = previous node number
|
|||
|
BSR.S GRGetNode ; get the previous node
|
|||
|
BNE.S GRExit1 ; error ->
|
|||
|
ADD.W NDNRecs(A3),D4 ; adjust index
|
|||
|
BRA.S @1 ; check bounds again ->
|
|||
|
|
|||
|
@4 MOVEQ #0,D4 ; new index mark = index of first record
|
|||
|
|
|||
|
@5 MOVE.L D3,BTCNodeM(A4) ; new node mark
|
|||
|
MOVE.W D4,BTCIndexM(A4) ; new index mark
|
|||
|
MOVEQ #BTnotfound,D0 ; set return code <14Oct85>
|
|||
|
BRA.S GRExit1 ; exit ->
|
|||
|
;
|
|||
|
; found the record, set up pointers to key and data
|
|||
|
;
|
|||
|
GRGotIt
|
|||
|
MOVE.W D4,D1 ; record index
|
|||
|
MOVEA.L A3,A1 ; ptr(node buffer)
|
|||
|
JSR ExtLocRec ; locate key and data record
|
|||
|
|
|||
|
MOVE.L D3,BTCNodeM(A4) ; update current node
|
|||
|
MOVE.W D4,BTCIndexM(A4) ; ...and index markers
|
|||
|
;
|
|||
|
; release node buffer and exit
|
|||
|
;
|
|||
|
GRExit
|
|||
|
CLR.W D0 ; result = ok
|
|||
|
GRExit1
|
|||
|
MOVEM.L D0-D1/A0-A1,-(A6) ; save return stuff
|
|||
|
BSR.S GRRelNode ; release node buffer
|
|||
|
MOVEM.L (A6)+,D0-D1/A0-A1 ; restore return stuff
|
|||
|
|
|||
|
MOVE.L D3,D2 ; hint = node number
|
|||
|
|
|||
|
BSR BTCleanUP ; clean up
|
|||
|
|
|||
|
MOVEM.L (A6)+,D3-D5/A2-A4 ; restore regs
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set condition codes
|
|||
|
RTS ; exit BTGetRecord
|
|||
|
|
|||
|
;
|
|||
|
; GRGetNode subroutine - releases current node and gets the next node.
|
|||
|
; A3.L = ptr(current node buffer)
|
|||
|
; D3.L = next node number
|
|||
|
;
|
|||
|
GRGetNode
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
BSR.S GRRelNode ; release current node
|
|||
|
MOVEQ #0,D1 ; no GetBlock options <10Oct85>
|
|||
|
MOVE.L D3,D2 ; node number
|
|||
|
JSR ExtGetNode ; get the node
|
|||
|
BNE.S @1 ; error -> <21Oct85>
|
|||
|
MOVEA.L A0,A3 ; A3 = ptr(next node buffer)
|
|||
|
@1 MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set condition codes
|
|||
|
RTS ; exit GRGetNode
|
|||
|
|
|||
|
|
|||
|
;
|
|||
|
; GRRelNode subroutine - releases current node buffer.
|
|||
|
; A3.L = ptr(current node buffer)
|
|||
|
;
|
|||
|
|
|||
|
GRRelNode
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
|
|||
|
MOVEQ #0,D1 ; no RelBlock options <10Oct85>
|
|||
|
MOVEA.L A3,A0 ; ptr(node buffer) <23Sep85>
|
|||
|
JSR ExtRelNode ; release the node
|
|||
|
SUBA.L A3,A3 ; indicate no node buffer
|
|||
|
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set condition codes
|
|||
|
RTS ; exit GRRelNode
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: BTInsert
|
|||
|
;
|
|||
|
; Function: Inserts a record into a BTree file given the
|
|||
|
; record key and data.
|
|||
|
;
|
|||
|
; Input: A0.L - address of key
|
|||
|
; A1.L - address of record data
|
|||
|
; D0.W - file refnum
|
|||
|
; D1.W - size of DATA record
|
|||
|
; D2.L - actual data size (in number of nodes) <23Feb90>
|
|||
|
; Output: D0.W - result code
|
|||
|
; 0 = ok
|
|||
|
; BTexists = key already exists
|
|||
|
; other = error
|
|||
|
; D2.L - BTree hint
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
ExtBTInsert ;
|
|||
|
; MOVE.L jBTInsert,-(SP) ; jumptable entry for vBTInsert <25Oct85>
|
|||
|
; RTS ; go there <25Oct85>
|
|||
|
;vBTInsert ; 'vectored' BTInsert routine <25Oct85>
|
|||
|
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D1/D3-D7/A0-A4,-(A6) ; save registers
|
|||
|
|
|||
|
JSR ExtLocBTCB ; locate BTCB
|
|||
|
|
|||
|
MOVE.L A1,D7 ; D7 = ptr(record)
|
|||
|
MOVE.W D1,D6 ; D6 = size of record
|
|||
|
MOVE.L A0,D5 ; D5 = ptr(key)
|
|||
|
;
|
|||
|
; make sure there is enough file space for a worst case split
|
|||
|
; In supporting the new special data record, no code needs to be changed at this lower
|
|||
|
; level (the data record (A1) and size (D1) are representing the special record, not the
|
|||
|
; actual data), except in allocating more disk space for the data. <23Feb90>
|
|||
|
|
|||
|
MOVEQ #1,D3 ; required space (in nodes) =
|
|||
|
ADD.W BTCDepth(A4),D3 ; tree depth + 1
|
|||
|
CMP.L BTCFree(A4),D3 ; enough space?
|
|||
|
BLE.S BIInit ; yes ->
|
|||
|
@1 JSR ExtExtBTFile ; extend the file
|
|||
|
BNE BIExit2 ; couldn't do it ->
|
|||
|
|
|||
|
CMP.L BTCFree(A4),D3 ; enough space now?
|
|||
|
BGT.S @1 ; no ->
|
|||
|
;
|
|||
|
; initialize some things
|
|||
|
;
|
|||
|
BIInit
|
|||
|
MOVE.W BTCRefNum(A4),D0 ; set up common stuff
|
|||
|
BSR BTSetUp ;
|
|||
|
|
|||
|
MOVEM.L D6/D7,-(A6) ;save input record size and ptr
|
|||
|
|
|||
|
MOVEQ #0,D4 ; indicate no parent node buffer <29Aug85>
|
|||
|
SUBA.L A2,A2 ; ...no left node buffer
|
|||
|
SUBA.L A3,A3 ; ...no right node buffer
|
|||
|
|
|||
|
CLR.L BTCNodeM(A4) ; invalidate current node mark
|
|||
|
;
|
|||
|
; build BTree record consisting of input key with a junk data record
|
|||
|
;
|
|||
|
MOVEA.L BTCVarPtr(A4),A1 ; dest = record buffer
|
|||
|
LEA ExtBTVRecord(A1),A1 ; maxDepth changed <11Apr90>
|
|||
|
MOVEA.L D5,A0 ; source = input key
|
|||
|
MOVEQ #0,D0 ; get key length
|
|||
|
MOVE.B (A0),D0 ;
|
|||
|
ADDQ.L #2,D0 ; include length byte
|
|||
|
LSR.L #1,D0 ;
|
|||
|
LSL.L #1,D0 ; ...and adjust to word boundry
|
|||
|
ADD.W D0,D6 ; total size = key size + data size
|
|||
|
_BlockMove ; move in the key
|
|||
|
|
|||
|
ADDQ.W #1,D6 ; adjust total size to word boundry
|
|||
|
LSR.W #1,D6 ;
|
|||
|
LSL.W #1,D6 ;
|
|||
|
MOVE.L A1,D7 ; D7 = ptr(Btree record)
|
|||
|
;
|
|||
|
; search tree for key
|
|||
|
;
|
|||
|
BISearch
|
|||
|
JSR ExtTreeSearch ; search for key
|
|||
|
MOVEA.L A1,A3 ; A3 = ptr(right node buffer)
|
|||
|
BNE.S @1 ; key not found or error ->
|
|||
|
MOVEQ #BTexists,D0 ; error, it already exists <14Oct85>
|
|||
|
BRA BIExit1 ; exit ->
|
|||
|
@1 CMP.W #BTnotfound,D0 ; key not found ?
|
|||
|
BNE BIExit1 ; no, must be IO error ->
|
|||
|
MOVE.L D2,D3 ; D3 = right node number
|
|||
|
MOVE.W D1,D5 ; D5 = insert index
|
|||
|
;
|
|||
|
; if tree is empty, add 1st leaf node
|
|||
|
;
|
|||
|
TST.W BTCLevel(A4) ; tree empty ?
|
|||
|
BGT.S BIInsert ; no ->
|
|||
|
|
|||
|
MOVE.W BTCRefNum(A4),D0 ; file refnum
|
|||
|
JSR ExtAllocNode ; allocate the node
|
|||
|
BNE BIExit1 ; error ->
|
|||
|
|
|||
|
MOVE.L D1,D3 ; D3 = new node number
|
|||
|
|
|||
|
JSR ExtInitNode ; get an initialized node
|
|||
|
BNE BIExit1 ; error -> <18Dec85>
|
|||
|
MOVEA.L A0,A3 ; A3 = ptr(new root node)
|
|||
|
|
|||
|
MOVE.B #NDLeafNode,NDType(A3) ; type = leaf node
|
|||
|
MOVEQ #1,D0 ; node height = 1
|
|||
|
MOVE.B D0,NDNHeight(A3) ;
|
|||
|
|
|||
|
MOVE.W D0,BTCDepth(A4) ; tree depth = 1
|
|||
|
MOVE.L D3,BTCRoot(A4) ; new root node number
|
|||
|
|
|||
|
MOVE.L D3,BTCFNode(A4) ; 1st and last node pointers
|
|||
|
MOVE.L D3,BTCLNode(A4) ;
|
|||
|
|
|||
|
MOVE.W #1,BTCLevel(A4) ; current level = 1
|
|||
|
;
|
|||
|
; try a simple insert first
|
|||
|
;
|
|||
|
BIInsert
|
|||
|
MOVEA.L D7,A0 ; ptr(record)
|
|||
|
MOVE.W D6,D0 ; record size
|
|||
|
MOVEA.L A3,A1 ; ptr(node buffer)
|
|||
|
MOVE.W D5,D1 ; insert index
|
|||
|
JSR ExtInsertRec ; try to insert it
|
|||
|
BNE.S BIRotate ; didn't make it ->
|
|||
|
|
|||
|
TST.W D5 ; insert a new 1st record ?
|
|||
|
BNE.S BIInsDone ; no, insert complete ->
|
|||
|
BSET #BTCKeyUpd,BTCFlags(A4) ; indicate key update required
|
|||
|
BRA.S BIInsDone ; insert complete ->
|
|||
|
;
|
|||
|
; insert didn't work, try rotation into left sibling node
|
|||
|
;
|
|||
|
BIRotate
|
|||
|
MOVEA.L A3,A0 ; ptr(node buffer)
|
|||
|
JSR ExtGetLtSib ; get left sibling node
|
|||
|
BNE BIExit1 ; error ->
|
|||
|
TST.L D1 ; is there a left sibling ?
|
|||
|
BEQ.S BISplit ; no ->
|
|||
|
MOVE.L D1,D2 ; D2 = left node number
|
|||
|
MOVEA.L A1,A2 ; A2 = ptr(left node buffer)
|
|||
|
|
|||
|
MOVEA.L D7,A0 ; ptr(record)
|
|||
|
MOVE.W D6,D0 ; record size
|
|||
|
MOVE.W D5,D1 ; insert index
|
|||
|
JSR ExtRotateLt ; try rotating left, and insert the record
|
|||
|
BNE.S BISplit ; didn't make it ->
|
|||
|
BRA.S BISplit1 ; use common code -> <10Oct85>
|
|||
|
;
|
|||
|
; rotate didn't work, got to split
|
|||
|
;
|
|||
|
BISplit MOVEA.L D7,A0 ; ptr(record)
|
|||
|
MOVE.W D6,D0 ; record size
|
|||
|
MOVE.W D5,D1 ; insert index
|
|||
|
JSR ExtSplitLT ; split left
|
|||
|
BEQ.S @1 ; ok ->
|
|||
|
MOVEQ #BTnoFit,D0 ; result = 'no fit' <14Oct85>
|
|||
|
BRA BIExit1 ; exit ->
|
|||
|
@1 BSET #BTCNewIRec,BTCFlags(A4) ; indicate new index record required <10Oct85>
|
|||
|
|
|||
|
BISplit1 ; <10Oct85>
|
|||
|
BSET #BTCKeyUpd,BTCFlags(A4) ; indicate key update required <10Oct85>
|
|||
|
MOVE.W D1,D5 ; D5 = new record index <10Oct85>
|
|||
|
|
|||
|
;; another problem with the new buffer scheme using ExtMarkBlock;<9/6/89>
|
|||
|
;; A1.L=ptr(node buffer) containing new record ;<9/6/89>
|
|||
|
CMPA.L A2,A1 ; new record in left node? ;<9/6/89>
|
|||
|
BNE.S @4 ; no ;<9/6/89>
|
|||
|
CMPI.B #NDleafNode,NDType(A1) ; leaf level? ;<9/6/89>
|
|||
|
BNE.S @4 ; no, -> ;<9/6/89>
|
|||
|
;; before we marking the leaf, update the data ;<9/6/89>
|
|||
|
MOVEM.L (A6),A0/D0 ; get input record ptr and size ;<9/6/89>
|
|||
|
JSR ExtUpdDRec ; replace the junk data record ;<9/6/89>
|
|||
|
@4 MOVEA.L A2,A0 ; mark the left node dirty <10Oct85>
|
|||
|
JSR ExtMarkBlock ; write it back <20Feb90>
|
|||
|
;
|
|||
|
; completed the record insert, clean up
|
|||
|
;
|
|||
|
BIInsDone
|
|||
|
;; We can't mark block before Updating the leaf record: <8/31/89>
|
|||
|
;; (because ExtMarkBlock is now writing block to cache)
|
|||
|
CMPI.B #NDleafNode,NDType(A1) ; leaf level? <8/31/89>
|
|||
|
BEQ.S @0 ; yes, -> <8/31/89>
|
|||
|
MOVEA.L A3,A0 ; no, not leaf <8/31/89>
|
|||
|
JSR ExtMarkBlock ; write it back <20Feb90>
|
|||
|
BRA.S BICkDone ; all done if not leaf <8/31/89>
|
|||
|
|
|||
|
@0 MOVEM.L (A6),A0/D0 ; get input record ptr and size <8/31/89>
|
|||
|
JSR ExtUpdDRec ; replace the junk data record <8/31/89>
|
|||
|
MOVEA.L A3,A0 ; update and then mark it <8/31/89>
|
|||
|
JSR ExtMarkBlock ; write it back <20Feb90>
|
|||
|
|
|||
|
ADD.L #1,BTCNRecs(A4) ; bump leaf record count
|
|||
|
|
|||
|
MOVE.W D5,BTCIndexM(A4) ; save index marker
|
|||
|
MOVE.L D3,D0 ; assume right node number
|
|||
|
CMPA.L A3,A1 ; is new record in right node?
|
|||
|
BEQ.S @1 ; yes ->
|
|||
|
MOVE.L D2,D0 ; no, use left node number
|
|||
|
@1 MOVE.L D0,BTCNodeM(A4) ; save node marker
|
|||
|
;
|
|||
|
; Check if all done
|
|||
|
;
|
|||
|
BICkDone
|
|||
|
BTST #BTCKeyUpd,BTCFlags(A4) ; key update required ?
|
|||
|
BNE.S BINxtLev ; yes, move to next level ->
|
|||
|
BTST #BTCNewIRec,BTCFlags(A4) ; new index record required ?
|
|||
|
BEQ BIExit ; no, all done ->
|
|||
|
;
|
|||
|
; move to next level
|
|||
|
;
|
|||
|
BINxtLev
|
|||
|
SUB.W #1,BTCLevel(A4) ; bump to next level up
|
|||
|
BEQ BIRoot ; up to root level ->
|
|||
|
|
|||
|
MOVE.W BTCLevel(A4),D0 ; locate TPR
|
|||
|
JSR ExtLocTPR ; for this level
|
|||
|
MOVE.W TPRRIndx(A0),D5 ; D5 = parent record index
|
|||
|
MOVE.L TPRNodeN(A0),D3 ; D3 = parent node number
|
|||
|
|
|||
|
MOVE.L D2,-(A6) ; save D2 (node hint)
|
|||
|
MOVEQ #0,D1 ; get parent node <10Oct85>
|
|||
|
MOVE.L D3,D2 ;
|
|||
|
JSR ExtGetNode ;
|
|||
|
|
|||
|
BNE BIExit1 ; error -> D2 on a6 ????? <KSCT>
|
|||
|
MOVE.L A0,D4 ; D4 = ptr(parent node buffer)
|
|||
|
MOVE.L (A6)+,D2 ; restore D2
|
|||
|
;
|
|||
|
; update parent key
|
|||
|
;
|
|||
|
BIUpdKey
|
|||
|
BTST #BTCKeyUpd,BTCFlags(A4) ; key update required ?
|
|||
|
BEQ.S @1 ; no ->
|
|||
|
|
|||
|
MOVE.W D5,D0 ; locate
|
|||
|
MOVEA.L D4,A1 ;
|
|||
|
JSR ExtGetRecA ; ...parent index record
|
|||
|
MOVE.L A0,-(SP) ; ...and save it
|
|||
|
MOVEA.L A3,A1 ; locate 1st key
|
|||
|
CLR.W D0 ;
|
|||
|
JSR ExtGetRecA ; ...in right node
|
|||
|
MOVEA.L (SP)+,A1 ; ptr(parent index record)
|
|||
|
|
|||
|
JSR ExtUpdIKey ; update the key
|
|||
|
|
|||
|
MOVEA.L D4,A0 ; mark the parent node dirty <10Oct85>
|
|||
|
JSR ExtMarkBlock ; write it back <20Feb90>
|
|||
|
|
|||
|
TST.W D5 ; update to 1st key in node ?
|
|||
|
BEQ.S @1 ; yes, leave flag set ->
|
|||
|
BCLR #BTCKeyUpd,BTCFlags(A4) ; don't need to update next level
|
|||
|
|
|||
|
@1 MOVEQ #0,D1 ; release <10Oct85>
|
|||
|
MOVEA.L A3,A0 ;
|
|||
|
JSR ExtRelNode ; ... right node buffer
|
|||
|
|
|||
|
MOVEA.L D4,A3 ; parent is new right node
|
|||
|
MOVEQ #0,D4 ; indicate no parent node buffer <29Aug85>
|
|||
|
;
|
|||
|
; build new index record pointing at new left node
|
|||
|
;
|
|||
|
BINewRec
|
|||
|
BTST #BTCNewIRec,BTCFlags(A4) ; new index record required ?
|
|||
|
BEQ.S @1 ; no ->
|
|||
|
|
|||
|
MOVEA.L A2,A1 ; left node
|
|||
|
MOVE.L D2,D0 ; left node number
|
|||
|
JSR ExtBuildIRec ; build index record
|
|||
|
|
|||
|
@1 MOVEQ #0,D1 ; release <10Oct85>
|
|||
|
MOVEA.L A2,A0 ;
|
|||
|
JSR ExtRelNode ; ... left node buffer
|
|||
|
SUBA.L A2,A2 ; indicate no left node
|
|||
|
;
|
|||
|
; set up for insert of new index record
|
|||
|
;
|
|||
|
BTST #BTCNewIRec,BTCFlags(A4) ; new index record required ?
|
|||
|
BEQ BICkDone ; no, check if done ->
|
|||
|
|
|||
|
MOVEA.L BTCVarPtr(A4),A0 ; locate new index record
|
|||
|
LEA ExtBTVRecord(A0),A0 ; maxDepth changed <11Apr90>
|
|||
|
MOVE.L A0,D7 ; D7 = ptr to new record
|
|||
|
JSR ExtGetMaxkey ; max key length + 4 <10Oct85>
|
|||
|
ADDQ.W #4,D0 ; = size of index record <10Oct85>
|
|||
|
MOVE.W D0,D6 ; D6 = size of new record <10Oct85>
|
|||
|
BCLR #BTCNewIRec,BTCFlags(A4) ; clear new index rec flag
|
|||
|
BRA BIInsert ; insert new index record ->
|
|||
|
;
|
|||
|
; we updated the root, must add a level if it was split
|
|||
|
;
|
|||
|
BIRoot
|
|||
|
BTST #BTCNewIRec,BTCFlags(A4) ; was root node split ?
|
|||
|
BEQ BIExit ; no, all done ->
|
|||
|
;
|
|||
|
; set up a new root index node
|
|||
|
;
|
|||
|
|
|||
|
MOVE.W BTCDepth(A4),D0 ; check tree depth <04Apr90>
|
|||
|
CMPI #ExtBTMaxDepth,D0 ; is this the limit? <11Apr90>
|
|||
|
BNE.S @0 ; no <04Apr90>
|
|||
|
IF btDebug THEN
|
|||
|
_debugger ; fatal error <04Apr90>
|
|||
|
ENDIF
|
|||
|
MOVE.W #btDepthErr,D0 ; punt on <04Apr90>
|
|||
|
BRA.S BIExit1 ; error -> <04Apr90>
|
|||
|
|
|||
|
@0 MOVE.W BTCRefNum(A4),D0 ; volume refnum
|
|||
|
JSR ExtAllocNode ; allocate the node
|
|||
|
BNE.S BIExit1 ; error ->
|
|||
|
|
|||
|
MOVE.L D1,D3 ; D3 = new root node number
|
|||
|
|
|||
|
MOVE.L D3,D1 ; new node number
|
|||
|
JSR ExtInitNode ; get an initialized node
|
|||
|
BNE.S BIExit1 ; error -> <18Dec85>
|
|||
|
MOVE.L A0,D4 ; D4 = ptr(new root node buffer)
|
|||
|
|
|||
|
MOVE.B #NDIndxNode,NDType(A0) ; type = index node
|
|||
|
MOVEQ #1,D0 ; node height
|
|||
|
ADD.W BTCDepth(A4),D0 ; = previous depth +1
|
|||
|
MOVE.B D0,NDNHeight(A0) ;
|
|||
|
;
|
|||
|
; add index record for left node
|
|||
|
;
|
|||
|
MOVEA.L A2,A1 ; build index record
|
|||
|
MOVE.L D2,D0 ;
|
|||
|
JSR ExtBuildIRec ; ...for left node
|
|||
|
|
|||
|
JSR ExtGetMaxkey ; max key length + 4 <10Oct85>
|
|||
|
ADDQ.W #4,D0 ; = size of index record <10Oct85>
|
|||
|
MOVEA.L BTCVarPtr(A4),A0 ; locate new index record
|
|||
|
LEA ExtBTVRecord(A0),A0 ; maxDepth changed <11Apr90>
|
|||
|
MOVEA.L D4,A1 ; ptr(root node buffer)
|
|||
|
CLR.W D1 ; insert index = 0
|
|||
|
JSR ExtInsertRec ; insert it
|
|||
|
;
|
|||
|
; add index record for right node (previous root)
|
|||
|
;
|
|||
|
MOVE.W #1,D0 ; get node number
|
|||
|
JSR ExtLocTPR ;
|
|||
|
MOVE.L TPRNodeN(A0),D0 ; ...of previous root
|
|||
|
MOVEA.L A3,A1 ; ptr(node buffer)
|
|||
|
JSR ExtBuildIRec ; build index record
|
|||
|
|
|||
|
JSR ExtGetMaxkey ; max key length + 4 <10Oct85>
|
|||
|
ADDQ.W #4,D0 ; = size of index record <10Oct85>
|
|||
|
MOVEA.L BTCVarPtr(A4),A0 ; locate new index record
|
|||
|
LEA ExtBTVRecord(A0),A0 ; maxDepth changed <11Apr90>
|
|||
|
MOVEA.L D4,A1 ; ptr(root node buffer)
|
|||
|
MOVE.W #1,D1 ; insert index = 1
|
|||
|
JSR ExtInsertRec ; insert it
|
|||
|
|
|||
|
MOVEA.L D4,A0 ; mark the new root node dirty <10Oct85>
|
|||
|
JSR ExtMarkBlock ; write it back <20Feb90>
|
|||
|
;
|
|||
|
; update BTCB
|
|||
|
;
|
|||
|
ADD.W #1,BTCDepth(A4) ; add a level
|
|||
|
MOVE.L D3,BTCRoot(A4) ; new root node number
|
|||
|
;
|
|||
|
; clean up and exit
|
|||
|
;
|
|||
|
BIExit
|
|||
|
BSET #BTCDirty,BTCFlags(A4) ; mark BTCB dirty
|
|||
|
CLR.W D0 ; result = ok
|
|||
|
BIExit1
|
|||
|
MOVE.W D0,-(A6) ; save result code
|
|||
|
|
|||
|
MOVEA.L A2,A0 ; ptr(left node buffer) <23Sep85>
|
|||
|
MOVEQ #0,D1 ; no RelBlock options <10Oct85>
|
|||
|
JSR ExtRelNode ; release it
|
|||
|
|
|||
|
MOVEA.L A3,A0 ; ptr(right node buffer) <23Sep85>
|
|||
|
JSR ExtRelNode ; release it
|
|||
|
|
|||
|
MOVEA.L D4,A0 ; ptr(parent node buffer) <23Sep85>
|
|||
|
JSR ExtRelNode ; release it
|
|||
|
|
|||
|
MOVE.W (A6)+,D0 ; restore result code
|
|||
|
|
|||
|
MOVE.L BTCNodeM(A4),D2 ; return hint (node number)
|
|||
|
CLR.L BTCNodeM(A4) ; invalidate current record markers
|
|||
|
|
|||
|
BSR BTCleanUP ; clean up
|
|||
|
|
|||
|
ADDQ.L #8,A6 ; deallocate saved stuff
|
|||
|
BIExit2
|
|||
|
MOVEM.L (A6)+,D1/D3-D7/A0-A4 ; restore regs
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set condition codes
|
|||
|
RTS ; exit BTInsert
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: BTSearch
|
|||
|
;
|
|||
|
; Function: Searches a BTree file for a record given the key. If a hint is
|
|||
|
; given, the BTree node identified by that hint is obtained and
|
|||
|
; searched first. Then, if the record is not found, a normal tree
|
|||
|
; search is performed.
|
|||
|
;
|
|||
|
; Input: A0.L - pointer to key
|
|||
|
; D0.W - file refnum
|
|||
|
; D2.L - BTree hint
|
|||
|
; 0 = no hint
|
|||
|
;
|
|||
|
; Output: D0.W - result code
|
|||
|
; 0 = ok
|
|||
|
; BTnotfound = record not found
|
|||
|
; other = error
|
|||
|
; A0.L - pointer to key
|
|||
|
; A1.L - pointer to data record
|
|||
|
; D1.W - size of data record
|
|||
|
; D2.L - new BTree hint
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
ExtBTSearch ;
|
|||
|
; MOVE.L jBTSearch,-(SP) ; jumptable entry for vBTSearch <25Oct85>
|
|||
|
; RTS ; go there <25Oct85>
|
|||
|
;vBTSearch ; 'vectored' BTSearch routine <25Oct85>
|
|||
|
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D3-D7/A2-A4,-(A6) ; save regs
|
|||
|
;
|
|||
|
; initialize some things
|
|||
|
;
|
|||
|
BSR BTSetUp ; set up common stuff
|
|||
|
|
|||
|
MOVEA.L A0,A3 ; A3 = ptr to key
|
|||
|
SUBA.L A2,A2 ; indicate no node buffer
|
|||
|
;
|
|||
|
; go directly to the leaf node if hint is given
|
|||
|
;
|
|||
|
TST.L D2 ; hint given?
|
|||
|
BEQ.S BSTSrch ; no, do tree search ->
|
|||
|
|
|||
|
MOVEQ #0,D1 ; get target node <10Oct85>
|
|||
|
JSR ExtGetNode ;
|
|||
|
BNE.S BSExit1 ; error -> <07Sep89>
|
|||
|
; this node has been released <07Sep89>
|
|||
|
MOVEA.L A0,A2 ; A2 = ptr(node buffer)
|
|||
|
|
|||
|
CMPI.B #NDLeafNode,NDType(A0) ; leaf node?
|
|||
|
BNE.S @1 ; no ->
|
|||
|
TST.W NDNRecs(A0) ; node empty?
|
|||
|
BLE.S @1 ; yes ->
|
|||
|
|
|||
|
MOVEA.L A3,A0 ; search node for key
|
|||
|
MOVEA.L A2,A1 ;
|
|||
|
JSR ExtSearchNode ;
|
|||
|
BEQ.S BSTSrch1 ; found it ->
|
|||
|
|
|||
|
@1 MOVEA.L A2,A0 ; release node buffer
|
|||
|
MOVEQ #0,D1 ; no RelBlock options <10Oct85>
|
|||
|
JSR ExtRelNode ;
|
|||
|
BNE.S BSExit1 ; error -> <07Sep89>
|
|||
|
;
|
|||
|
; search tree for key
|
|||
|
;
|
|||
|
BSTSrch
|
|||
|
MOVEA.L A3,A0 ; ptr to key
|
|||
|
JSR ExtTreeSearch ; search tree for key
|
|||
|
MOVEA.L A1,A2 ; A2 = ptr(node buffer)
|
|||
|
BEQ.S BSTSrch1 ; key found ->
|
|||
|
CMP.W #BTnotfound,D0 ; key not found error ?
|
|||
|
BNE.S BSExit1 ; no, must be IO error ->
|
|||
|
BSTSrch1 MOVE.W D1,D5 ; D5 = record index
|
|||
|
MOVE.W D0,-(A6) ; save search result
|
|||
|
;
|
|||
|
; update current markers in BTCB
|
|||
|
;
|
|||
|
MOVE.L D2,BTCNodeM(A4) ; update current node mark
|
|||
|
MOVE.W D5,BTCIndexM(A4) ; ... and record index mark
|
|||
|
;
|
|||
|
; set up pointers to key and data record
|
|||
|
;
|
|||
|
TST.W (A6) ; record found?
|
|||
|
BNE.S BSExit ; no ->
|
|||
|
MOVE.W D5,D0 ; record index
|
|||
|
MOVEA.L A2,A1 ; ptr(node buffer)
|
|||
|
JSR ExtLocRec ; locate the record
|
|||
|
;
|
|||
|
; release node buffer and exit
|
|||
|
;
|
|||
|
BSExit
|
|||
|
MOVEM.L D1-D2/A0-A1,-(A6) ; save return stuff
|
|||
|
|
|||
|
MOVEA.L A2,A0 ; ptr(node buffer) <23Sep85>
|
|||
|
MOVEQ #0,D1 ; no RelBlock options <10Oct85>
|
|||
|
JSR ExtRelNode ; release it
|
|||
|
MOVEM.L (A6)+,D1-D2/A0-A1 ; restore return stuff
|
|||
|
|
|||
|
MOVE.W (A6)+,D0 ; restore search result
|
|||
|
BSExit1
|
|||
|
BSR.S BTCleanUP ; clean up
|
|||
|
|
|||
|
MOVEM.L (A6)+,D3-D7/A2-A4 ; restore regs
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set condition codes
|
|||
|
RTS ; exit BTSearch
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Routine: ExtBTUpdate
|
|||
|
;
|
|||
|
; Function: Marks a buffer containing the specified BTree node as being
|
|||
|
; updated (dirty).
|
|||
|
;
|
|||
|
; Input: D0.L - file refnum
|
|||
|
; D2.L - BTree hint (node number of dirty node)
|
|||
|
;
|
|||
|
; Output: D0.W - result code
|
|||
|
; 0 = ok
|
|||
|
; BTnotfound = node not found
|
|||
|
; other = IO error
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
ExtBTUpdate
|
|||
|
|
|||
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|||
|
MOVEM.L D1/A0-A1/A4,-(A6) ; save regs
|
|||
|
|
|||
|
JSR ExtLocBTCB ; locate BTCB
|
|||
|
|
|||
|
MOVEQ #kGBexist,D1 ; indicate existing cache block <10Oct85>
|
|||
|
JSR ExtGetNode ; get the node
|
|||
|
BNE.S BUExit ; error ->
|
|||
|
|
|||
|
MOVEQ #kRBdirty,D1 ; indicate dirty buffer
|
|||
|
JSR ExtRelNode ; release the node
|
|||
|
BNE.S BUExit ; error ->
|
|||
|
|
|||
|
CLR.W D0 ; indicate no error
|
|||
|
BUExit
|
|||
|
MOVEM.L (A6)+,D1/A0-A1/A4 ; restore regs
|
|||
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|||
|
TST.W D0 ; set condition codes
|
|||
|
RTS ; exit ExtBTUpdate
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Internal Subroutines
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Subroutine: BTCleanUp (BTree Clean Up)
|
|||
|
;
|
|||
|
; Function: Cleans up after a BTree service call. Space for the BTree
|
|||
|
; variable storage area (BTVars) is released and the pointer to
|
|||
|
; BTVars in the BTCB is cleared.
|
|||
|
;
|
|||
|
; Input: A4.L - pointer to BTCB
|
|||
|
;
|
|||
|
; Output: none
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
BTCleanUp
|
|||
|
MOVE.L D0,-(SP) ; save registers
|
|||
|
|
|||
|
BSR.S CalBTVars ; calculate size of BTVars
|
|||
|
ADDA.L D0,A6 ; remove BTVars from A6 stack
|
|||
|
CLR.L BTCVarPtr(A4) ; clear pointer in BTCB
|
|||
|
|
|||
|
MOVE.L (SP)+,D0 ; restore registers
|
|||
|
RTS ; exit BTCleanUp
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Subroutine: BTSetUp (BTree Set Up)
|
|||
|
;
|
|||
|
; Function: Sets up for a BTree service call. The BTCB is located and space
|
|||
|
; for the BTree variable storage area (BTVars) is allocated on the
|
|||
|
; A6 stack. A pointer to BTVars is saved in the BTCB. All call-
|
|||
|
; specific status flags in the BTCB are also cleared.
|
|||
|
;
|
|||
|
; Input: D0.W - file refnum
|
|||
|
;
|
|||
|
; Output: A4.L - pointer to BTCB
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
BTSetUp
|
|||
|
MOVE.L D0,-(SP) ; save registers
|
|||
|
|
|||
|
JSR ExtLocBTCB ; locate the BTCB
|
|||
|
|
|||
|
BSR.S CalBTVars ; calculate size of BTVars
|
|||
|
SUBA.L D0,A6 ; allocate space on A6 stack
|
|||
|
MOVE.L A6,BTCVarPtr(A4) ; save pointer in BTCB
|
|||
|
|
|||
|
BCLR #BTCNewIRec,BTCFlags(A4) ; clear status flags
|
|||
|
BCLR #BTCDelIRec,BTCFlags(A4) ;
|
|||
|
BCLR #BTCKeyUpd,BTCFlags(A4) ;
|
|||
|
|
|||
|
MOVE.L (SP)+,D0 ; restore registers
|
|||
|
RTS ; exit BTSetUp
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
;__________________________________________________________________________________
|
|||
|
;
|
|||
|
; Subroutine: CalBTVars (Calculate size of BTVars)
|
|||
|
;
|
|||
|
; Function: Calculates the size of the BTree variable storage area (BTVars).
|
|||
|
;
|
|||
|
; Input: A4.L - pointer to BTCB
|
|||
|
;
|
|||
|
; Output: D0.L - size of BTVars
|
|||
|
;__________________________________________________________________________________
|
|||
|
|
|||
|
CalBTVars
|
|||
|
JSR ExtGetMaxkey ; get max key size <10Oct85>
|
|||
|
ADDI.W #ExtlenTPT+4,D0 ; size of BTVars = length of TPT <11Apr90>
|
|||
|
|
|||
|
RTS ; exit CalBTVars
|
|||
|
|
|||
|
END
|
|||
|
|
|||
|
|