mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-09 02:30:13 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
1176 lines
34 KiB
Plaintext
1176 lines
34 KiB
Plaintext
;
|
|
; File: BTreeMaint2.a
|
|
;
|
|
; Revision by: Kenny SC. Tung
|
|
;
|
|
; Copyright: © 1984-1990, 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.
|
|
; ¥ Pre-SuperMario comments follow ¥
|
|
; <6> 8/3/90 KST Total number of nodes is calculated based on LEOF, not PEOF (in
|
|
; ExtChkNode).
|
|
; <5> 7/6/90 KST Fixing a bug in "ExtUpdIKey" which should not do EXT.W
|
|
; <4> 4/11/90 KST Code cleanup.
|
|
; <3> 4/11/90 KST Use ExtbtMaxDepth and related equates. <SM1>
|
|
; <2> 3/13/90 KST Adding for the first time.
|
|
; <1.1> 8/7/89 KST Code cleanup.
|
|
; <1.0> 6/14/89 KST New file added for the new implementation of BTreeMgr.
|
|
; <1.3> 5/4/89 KST Fixed a bug in ExtGetMaxkey.
|
|
; 5/4/89 KST Fixed a bug in ExtGetMaxkey, should add 2, not 1
|
|
; <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É
|
|
; 10/25/85 BB Added vectors for ROM versions.
|
|
; 10/22/85 BB Moved ExtLocBTCB from BTIntf to ExtBTMaint2.
|
|
; 10/10/85 BB Added use of new MOVEQ equates for GetBlock and RelBlock. Added
|
|
; ExtGetMaxkey subroutine and a call to it in ExtBuildIRec. Did some
|
|
; minor code clean up.
|
|
; 9/26/85 BB Modified ExtGetNode to release the cache block after detecting a
|
|
; bad BTree node.
|
|
; 9/24/85 PWD Changed '.Word $F042' to _TFSDSErr macro.
|
|
; 9/23/85 BB Added ExtClrNode and a call to it in ExtInitNode.
|
|
; 9/23/85 BB Modified ExtRelNode to handle a null node pointer and to call
|
|
; ExtChkNode.
|
|
; 9/6/85 BB Fixed minor bugs in ExtGetNodeSiz and GetOffA.
|
|
; 8/29/85 BB Changed ExtChkNode to use a more efficient method for checking
|
|
; record offsets.
|
|
; 8/22/85 BB Added ExtGetNode,ExtRelNode, and ExtChkNode.
|
|
; 8/8/85 BB Modified ExtGetOffset and ExtInitNode for new node format.
|
|
; 7/31/85 BB Fixed bug in ExtLocRec which was causing the "write" problem.
|
|
; 7/17/85 BB Added ExtGetNodeSiz. Modified ExtGetRecA to also return record size.
|
|
; 7/8/85 BB Modified ExtGetLtSib/ExtGetRtSib to use links to locate sibling nodes
|
|
; instead of using the TPT.
|
|
; 6/10/85 BB Cleaned up some.
|
|
; 3/15/85 BB Modified to use A6 stack.
|
|
; 3/11/85 BB Added extend BTree file stuff.
|
|
; 2/25/85 BB Modified ExtInsertRec to return node number and record index of new
|
|
; record.
|
|
; 2/18/85 BB Modified ExtLocRec to support variable length keys in leaf nodes.
|
|
; 2/13/85 BB Removed default KeyCompare routine
|
|
; 1/17/85 BB Removed use of BTree Global area (BTG).
|
|
; 1/5/85 BB Modified ExtSearchNode to use external key compare routine.
|
|
; 1/5/85 BB Added KeyCompare routine.
|
|
; 1/5/85 BB Changed CopyRec to ExtLocRec to support return of key and data
|
|
; record pointers instead of copying that data.
|
|
; 10/1/84 BB Split off from BTmaint.
|
|
;
|
|
; To Do:
|
|
;
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; FILE: ExtBTMaint2.text
|
|
;
|
|
; Function: These routines provide single-node BTree maintenance functions.
|
|
;
|
|
; External
|
|
; Routines: ExtBuildIRec - Builds an index record for a specified target node.
|
|
; ExtChkNode - Checks the validity of a node.
|
|
; ExtClrNode - Clears a node (to zero).
|
|
; ExtDeleteRec - Deletes a record from a BTree node.
|
|
; ExtGetMaxkey - Gets max key size rounded to word boundry.
|
|
; ExtGetNode - Gets a BTree node from disk.
|
|
; ExtGetNodeSiz - Gets the size of the data currently contained in a
|
|
; node (record data + offset overhead).
|
|
; ExtGetLtSib - Gets left sibling node for a given BTree node.
|
|
; ExtGetRtSib - Gets right sibling node for a given BTree node.
|
|
; ExtGetOffset - Gets the record offset and the pointer to the offset
|
|
; word for a given record index.
|
|
; ExtGetRecA - Gets the address of the record for a given record
|
|
; index.
|
|
; ExtInitNode - Gets a cache buffer for a new node and initializes it to
|
|
; an empty state.
|
|
; ExtInsertRec - Inserts a record into a BTree node.
|
|
; ExtLocBTCB - Locates the BTCB for a BTree file.
|
|
; ExtLocRec - Locates the key and data records for a specified
|
|
; BTree record.
|
|
; ExtLocTPR - Locates the Tree Path Record (TPR) for a given tree
|
|
; level.
|
|
; ExtMovOffLt - Move offsets left within a single node.
|
|
; ExtMovOffRt - Move offsets right within a single node.
|
|
; ExtMovRecLt - Move records left within a single node.
|
|
; ExtMovRecRt - Move records right within a single node.
|
|
; ExtRelNode - Releases the use of a node.
|
|
; ExtSearchNode - Searches a BTree node for a specified key.
|
|
; ExtUpdDRec - Updates the data portion of a BTree record.
|
|
; ExtUpdIKey - Updates the key portion of an index record.
|
|
;
|
|
; Internal
|
|
; Subroutines: None.
|
|
;
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
PRINT OFF
|
|
LOAD 'StandardEqu.d'
|
|
INCLUDE 'BtreeEqu.a'
|
|
INCLUDE 'BtreePrivate.a' ; Use ExtbtMaxDepth <11Apr90><SM1>
|
|
PRINT ON
|
|
PRINT NOGEN
|
|
|
|
ExtBTMaint2 PROC EXPORT
|
|
|
|
EXPORT ExtBuildIRec,ExtChkNode,ExtClrNode,ExtDeleteRec
|
|
EXPORT ExtGetMaxkey,ExtGetNode,ExtGetNodeSiz,ExtGetLtSib,ExtGetRtSib,ExtGetOffset,ExtGetRecA
|
|
EXPORT ExtInitNode,ExtInsertRec,ExtLocBTCB,ExtLocRec,ExtLocTPR
|
|
EXPORT ExtMovOffLt,ExtMovOffRt,ExtMovRecLt,ExtMovRecRt
|
|
EXPORT ExtRelNode,ExtSearchNode,ExtUpdDRec,ExtUpdIKey
|
|
|
|
IMPORT ExtGetBlock,ExtRelBlock ; <SM1>
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtBuildIRec
|
|
;
|
|
; Function: Builds an index record for a specified target node. The
|
|
; record is built in the BTree buffer.
|
|
;
|
|
; Input: A1.L - ptr(target node buffer)
|
|
; D0.W - target node number
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output: A1.L - ptr(new index record) in BTree buffer
|
|
;
|
|
; Called by: BTInsert
|
|
;__________________________________________________________________________________
|
|
|
|
ExtBuildIRec
|
|
MOVE.L D2,-(SP) ; save regs
|
|
MOVE.L D0,D2 ; save node number
|
|
|
|
CLR.W D0 ; locate 1st record
|
|
BSR ExtGetRecA ; ...in node
|
|
MOVEA.L BTCVarPtr(A4),A1 ; locate record buffer
|
|
LEA ExtbtVRecord(A1),A1 ; <11Apr90><SM1>
|
|
JSR ExtUpdIKey ; move in the key
|
|
|
|
BSR ExtGetMaxkey ; node # offset = max key size <10Oct85>
|
|
MOVE.L D2,0(A1,D0.W) ; move in the node number <10Oct85>
|
|
|
|
MOVE.L (SP)+,D2 ; restore regs
|
|
RTS ; exit ExtBuildIRec
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtChkNode
|
|
;
|
|
; Function: Checks the validity of a node.
|
|
;
|
|
; Input: A1.L - pointer to node buffer
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output D0.W - result code
|
|
; 0 - ok
|
|
; BTBadNode - bad node structure detected
|
|
;
|
|
; Called by: ExtGetNode
|
|
; <26Jul90> KSCT use LEOF to calculate total nodes.
|
|
;__________________________________________________________________________________
|
|
ExtChkNode
|
|
MOVEM.L D1-D2/A0-A2,-(SP) ; save registers
|
|
|
|
MOVE.W BTCRefNum(A4),D1 ; locate the FCB
|
|
MOVEA.L FCBSPtr,A2 ;
|
|
;
|
|
; check out the links
|
|
;
|
|
MOVE.L FCBEof(A2,D1.W),D0 ; LEOF / node size <26Jul90>
|
|
DIVU BTCNodeSize(A4),D0 ; = end node # + 1
|
|
MOVEQ #0,D1 ;
|
|
MOVE.W D0,D1 ; D1 = end node # + 1
|
|
|
|
CMP.L NDFlink(A1),D1 ; forward link within range?
|
|
BLS.S CNBadNode ; no, error ->
|
|
|
|
CMP.L NDBlink(A1),D1 ; backward link within range?
|
|
BLS.S CNBadNode ; no, error ->
|
|
;
|
|
; check node type
|
|
; note: valid node types are $FF (leaf node) to $02 (map node)
|
|
;
|
|
MOVE.B NDType(A1),D0 ; node type + 1
|
|
ADDQ.B #1,D0 ;
|
|
CMP.B #NDMapNode+1,D0 ; (node type +1) > (max type +1) ?
|
|
BHI.S CNBadNode ; yes, error ->
|
|
;
|
|
; check node height
|
|
;
|
|
MOVE.B NDNHeight(A1),D0 ; node height > tree depth?
|
|
CMP.B BTCDepth+1(A4),D0 ;
|
|
BHI.S CNBadNode ; yes, error ->
|
|
;
|
|
; check number of records
|
|
;
|
|
CNChkNRecs
|
|
MOVEQ #0,D1 ; D1 = node size
|
|
MOVE.W BTCNodeSize(A4),D1 ;
|
|
MOVEQ #-lenND,D0 ; max number of records
|
|
ADD.L D1,D0 ; = (node size - length of ND)
|
|
DIVU #6,D0 ; / (min record size + offset word)
|
|
CMP.W NDNRecs(A1),D0 ; record count within range?
|
|
BLO.S CNBadNode ; no, error ->
|
|
;
|
|
; check record offsets
|
|
;
|
|
CNChkOff
|
|
MOVE.W NDNRecs(A1),D1 ; loop index = # records
|
|
|
|
MOVE.W D1,D0 ; locate free space offset <29Aug85>
|
|
BSR ExtGetOffset ;
|
|
MOVEQ #2,D2 ; prime previous offset to <29Aug85>
|
|
ADD.L A0,D2 ; ptr(free space offset) + 2 <29Aug85>
|
|
SUB.L A1,D2 ; - ptr(node) <29Aug85>
|
|
|
|
@1 MOVE.W (A0)+,D0 ; get next offset <29Aug85>
|
|
BTST #0,D0 ; odd offset?
|
|
BNE.S CNBadNode ; yes, error ->
|
|
|
|
CMPI.W #LenND,D0 ; offset >= min ?
|
|
BLO.S CNBadNode ; no, error ->
|
|
CMP.W D2,D0 ; offset < previous ?
|
|
BHS.S CNBadNode ; no, error ->
|
|
|
|
MOVE.W D0,D2 ; previous offset = current offset
|
|
|
|
DBRA D1,@1 ; check next one ->
|
|
BRA.S CNExit ; all done ->
|
|
;
|
|
; clean up and exit
|
|
;
|
|
CNBadNode
|
|
MOVEQ #BTBadNode,D0 ; result = 'bad node' <14Oct85>
|
|
BRA.S CNExit1 ; exit ->
|
|
CNExit
|
|
CLR.W D0 ; result = 'ok'
|
|
CNExit1
|
|
MOVEM.L (SP)+,D1-D2/A0-A2 ; restore registers
|
|
TST.W D0 ; set up condition codes
|
|
RTS ; exit ExtChkNode
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtClrNode
|
|
;
|
|
; Function: Clears a node to all zeroes.
|
|
;
|
|
; Input: A0.L - pointer to node buffer
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output none
|
|
;
|
|
; Called by: BTDelete
|
|
;__________________________________________________________________________________
|
|
|
|
ExtClrNode
|
|
MOVEM.L D0-D1/A0,-(SP) ; save registers <23Sep85>
|
|
|
|
MOVEQ #3,D1 ; loop index <10Oct85>
|
|
ADD.W BTCNodeSize(A4),D1 ; = node size <10Oct85>
|
|
LSR.W #2,D1 ; (in long words) <23Sep85>
|
|
SUBQ.W #1,D1 ; - 1 <23Sep85>
|
|
|
|
MOVEQ #0,D0 ; clear the node buffer <23Sep85>
|
|
@1 MOVE.L D0,(A0)+ ; <23Sep85>
|
|
DBRA D1,@1 ; <23Sep85>
|
|
|
|
MOVEM.L (SP)+,D0-D1/A0 ; restore registers <23Sep85>
|
|
RTS ; exit ExtClrNode <23Sep85>
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtDeleteRec
|
|
;
|
|
; Function: Deletes a record from a BTree node.
|
|
;
|
|
; Input: A1.L - ptr(node buffer)
|
|
; D1.W - index of record to be deleted
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output: none
|
|
;
|
|
; Called by: BTDelete,RotRecLt
|
|
;__________________________________________________________________________________
|
|
|
|
ExtDeleteRec
|
|
MOVEM.L D2-D6/A2-A5,-(SP) ; save regs
|
|
;
|
|
; set up some common stuff
|
|
;
|
|
MOVE.W D1,D5 ; save delete index
|
|
|
|
MOVE.W D1,D0 ; get delete offset
|
|
JSR ExtGetOffset ;
|
|
MOVE.L A0,D6 ; ...D6 = ptr(delete offset)
|
|
MOVE.W D0,D4 ; ...D4 = delete offset
|
|
|
|
LEA -2(A0),A3 ; A3 = ptr(next offset)
|
|
MOVE.W (A3),D3 ; D3 = next offset
|
|
|
|
MOVE.W NDNRecs(A1),D0 ; get last offset
|
|
JSR ExtGetOffset ;
|
|
MOVE.L A0,A2 ; ...A2 = ptr(last offset)
|
|
MOVE.W D0,D2 ; ...D2 = last offset
|
|
;
|
|
; Compress remaining records
|
|
;
|
|
MOVE.L A1,A5 ; save ptr(node buffer)
|
|
LEA 0(A5,D3.W),A0 ; source = ptr(next record)
|
|
LEA 0(A5,D4.W),A1 ; dest = ptr(delete record)
|
|
MOVE.W D2,D0 ; count = last offset
|
|
SUB.W D3,D0 ; - next offset
|
|
JSR ExtMovRecLt ; move the records
|
|
|
|
SUB.W #1,NDNRecs(A5) ; decrement number of keys
|
|
|
|
;
|
|
; Adjust the offsets
|
|
;
|
|
MOVE.L A3,A0 ; source = ptr(next offset)
|
|
MOVE.L D6,A1 ; dest = ptr(delete offset)
|
|
MOVE.W NDNRecs(A5),D0 ; count = last index
|
|
SUB.W D5,D0 ; - delete index
|
|
MOVE.W D4,D1 ; delta = delete offset
|
|
SUB.W D3,D1 ; - next offset
|
|
JSR ExtMovOffRt ; adjust the offsets
|
|
|
|
DRExit
|
|
MOVEM.L (SP)+,D2-D6/A2-A5 ; restore regs
|
|
RTS ; return
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routines: ExtGetLtSib (Get Left Sibling)
|
|
; ExtGetRtSib (Get Right Sibling)
|
|
;
|
|
; Function: Gets the left or right sibling node for a given BTree node. The
|
|
; sibling nodes are located using the forward/backward node links.
|
|
;
|
|
; Input: A0.L - pointer to node buffer containing subject node
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output: A1.L - pointer to node buffer containing sibling node
|
|
; D1.L - node number of sibling node
|
|
; 0 - no sibling
|
|
; D0.W - result code
|
|
; 0 - ok
|
|
; -n - IO error
|
|
;__________________________________________________________________________________
|
|
|
|
ExtGetLtSib
|
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|
MOVEM.L D2-D3,-(A6) ; save registers
|
|
CLR.B D3 ; indicate ExtGetLtSib
|
|
BRA.S GSRtSib1 ; use common code
|
|
|
|
ExtGetRtSib
|
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|
MOVEM.L D2-D3,-(A6) ; save registers
|
|
MOVEQ #1,D3 ; indicate ExtGetRtSib
|
|
GSRtSib1
|
|
TST.B D3 ; getting left sibling ?
|
|
BNE.S @2 ; no ->
|
|
MOVE.L NDBlink(A0),D2 ; left sibling node number
|
|
BRA.S @3 ; ->
|
|
@2 MOVE.L NDFlink(A0),D2 ; right sibling node number
|
|
@3 BNE.S @5 ; we have the sibling ->
|
|
@4 CLR.L D1 ; indicate no sibling
|
|
BRA.S GSExit ; exit
|
|
|
|
@5 MOVEQ #0,D1 ; no GetBlock options <10Oct85>
|
|
BSR.S ExtGetNode ; get node from disk
|
|
BNE.S GSExit1 ; error ->
|
|
|
|
MOVE.L D2,D1 ; return the node number
|
|
MOVE.L A0,A1 ; ...and buffer address
|
|
GSExit
|
|
CLR.W D0 ; indicate no error
|
|
GSExit1
|
|
MOVEM.L (A6)+,D2-D3 ; restore registers
|
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|
TST.W D0 ; set up condition codes
|
|
RTS ; exit ExtGetLtSib/ExtGetRtSib
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtGetMaxkey
|
|
;
|
|
; Function: Gets maximum key size rounded to word boundry.
|
|
;
|
|
; Input: A4.L - pointer to BTCB
|
|
;
|
|
; Output D0.W - maximum key length
|
|
;
|
|
; Called by: BTInsert,BTDelete,BTGetRecord,BTSearch
|
|
;__________________________________________________________________________________
|
|
|
|
ExtGetMaxkey
|
|
MOVEQ #2,D0 ; key length = 1 <10Oct85>
|
|
; 2, include length byte <K.Tung 5/4/89>
|
|
ADD.W BTCKeyLen(A4),D0 ; + max key length <10Oct85>
|
|
LSR.W #1,D0 ; rounded down <10Oct85>
|
|
LSL.W #1,D0 ; <10Oct85>
|
|
|
|
RTS ; exit ExtGetMaxkey <10Oct85>
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtGetNode
|
|
;
|
|
; Function: Gets an existing BTree node from disk and verifies it.
|
|
; Note: this is a temporary interface, it will change for the new
|
|
; cache.
|
|
;
|
|
; Input: D1.B - GetBlock option flags
|
|
; D2.L - node number of desired node
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output D0.W - result code
|
|
; 0 = ok
|
|
; -n = error
|
|
; A0.L - pointer to buffer containing node
|
|
;
|
|
; Called by: BTInsert,BTDelete,BTGetRecord,BTSearch
|
|
;__________________________________________________________________________________
|
|
|
|
ExtGetNode
|
|
|
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|
MOVEM.L D1/A1,-(A6) ; save registers
|
|
|
|
MOVE.W BTCRefNum(A4),D0 ; file refnum
|
|
MOVEA.L BTCCQptr(A4),A1 ; ptr to cache queue
|
|
JSR ExtGetBlock ; get the block <SM1>
|
|
BNE.S GNExit ; didn't get it ->
|
|
|
|
MOVEA.L A0,A1 ; verify the node
|
|
BSR ExtChkNode ;
|
|
BEQ.S GNExit ; its ok -> <26Sep85>
|
|
|
|
MOVE.W D0,-(A6) ; save result code <26Sep85>
|
|
MOVEQ #kRBTrash,D1 ; set trash option <10Oct85>
|
|
MOVEA.L BTCCQptr(A4),A1 ; ptr to cache queue <26Sep85>
|
|
JSR ExtRelBlock ; release it <26Sep85><SM1>
|
|
MOVE.W (A6)+,D0 ; restore result code <26Sep85>
|
|
GNExit
|
|
MOVEM.L (A6)+,D1/A1 ; restore registers
|
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|
TST.W D0 ; set up condition codes
|
|
RTS ; exit ExtGetNode
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtGetNodeSiz (Get Node Size)
|
|
;
|
|
; Function: Gets the size of the data currently contained in a node
|
|
; (record data + offset overhead).
|
|
;
|
|
; Input: A1.L - pointer to node buffer
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output: D0.W - size of node data
|
|
;__________________________________________________________________________________
|
|
|
|
ExtGetNodeSiz
|
|
MOVE.L D1,-(SP) ; save registers
|
|
MOVE.W NDNRecs(A1),D1 ; number of records in node
|
|
MOVE.W D1,D0 ; record data size
|
|
JSR ExtGetOffset ; = free space offset
|
|
SUBI.W #lenND,D0 ; - length of ND <06Sep85>
|
|
LSL.W #1,D1 ; NRecs X 2 = overhead for offsets
|
|
ADD.W D1,D0 ; rec data size + offsets = node data size
|
|
|
|
MOVE.L (SP)+,D1 ; restore registers
|
|
RTS ; exit ExtGetNodeSiz
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtGetOffset (Get Offset)
|
|
;
|
|
; Function: Gets the record offset and the pointer to the offset word
|
|
; for a given record index.
|
|
;
|
|
; Input: A1.L - pointer to node buffer
|
|
; D0.W - record index
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output: D0.W - record offset
|
|
; A0.L - address of offset word
|
|
;__________________________________________________________________________________
|
|
|
|
ExtGetOffset
|
|
BSR.S GetOffA ; get ptr(offset) first
|
|
MOVE.W (A0),D0 ; get the offset
|
|
RTS ; return
|
|
|
|
;
|
|
; GetOffA (Get Offset Address) subroutine
|
|
;
|
|
GetOffA
|
|
SUBA.L A0,A0 ; position to offset base + 2 <06Sep85>
|
|
MOVE.W BTCNodeSize(A4),A0 ; <06Sep85>
|
|
ADDA.L A1,A0 ; <06Sep85>
|
|
LSL.W #1,D0 ; index * 2 (bytes)
|
|
NEG.W D0 ; negative byte index
|
|
LEA -2(A0,D0.W),A0 ; ptr(offset) = (base - 2) + byte index
|
|
RTS ; return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtGetRecA (Get Record Address)
|
|
;
|
|
; Function: Gets the address and size of a BTree record given the record index.
|
|
;
|
|
; Input: A1.L - ptr(node buffer)
|
|
; D0.W - record index
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output: A0.L - record address
|
|
; D0.W - size of record
|
|
;__________________________________________________________________________________
|
|
|
|
ExtGetRecA
|
|
MOVEM.L D1-D2,-(SP) ; save registers
|
|
MOVE.W D0,D1 ; D1 = record index
|
|
|
|
BSR.S ExtGetOffset ; get offset of target record
|
|
MOVE.W D0,D2 ; D2 = target offset
|
|
|
|
MOVE.W D1,D0 ; get offset to next record
|
|
ADDQ.W #1,D0 ;
|
|
BSR.S ExtGetOffset ;
|
|
|
|
SUB.W D2,D0 ; size = next offset - target offset
|
|
LEA 0(A1,D2.W),A0 ; ptr(record) = base + offset
|
|
|
|
MOVEM.L (SP)+,D1-D2 ; restore registers
|
|
RTS ; return
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtInitNode
|
|
;
|
|
; Function: Gets a cache buffer for a new node and initializes it to
|
|
; an empty state.
|
|
;
|
|
; Input: D1.L - node number of new node
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output D0.W - result code
|
|
; A0.L - ptr(cache buffer containing node)
|
|
;
|
|
; Called by: BTInsert
|
|
;__________________________________________________________________________________
|
|
|
|
ExtInitNode
|
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|
MOVEM.L D1-D2/A1,-(A6) ; save registers
|
|
|
|
;
|
|
; get cache buffer for new node
|
|
;
|
|
@1 MOVE.L D1,D2 ; node number
|
|
MOVE.W BTCRefNum(A4),D0 ; file refnum
|
|
MOVEQ #kGBnoread,D1 ; no-read option <10Oct85>
|
|
MOVEA.L BTCCQptr(A4),A1 ; cache queue ptr
|
|
JSR ExtGetBlock ; get cache buffer <SM1>
|
|
BNE.S INExit1 ; error ->
|
|
;
|
|
; initialize the node
|
|
;
|
|
BSR ExtClrNode ; clear the node first <23Sep85>
|
|
|
|
MOVE.W BTCNodeSize(A4),D2 ; D2 = node size
|
|
MOVE.W #lenND,-2(A0,D2.W) ; set free space offset
|
|
INExit
|
|
CLR.W D0 ; result = ok
|
|
INExit1
|
|
MOVEM.L (A6)+,D1-D2/A1 ; restore registers
|
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|
TST.W D0 ; set condition codes
|
|
RTS ; exit ExtInitNode
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtInsertRec
|
|
;
|
|
; Function: Inserts a record into a BTree node.
|
|
;
|
|
; Input: A0.L - pointer to record (to insert)
|
|
; A1.L - ptr(node buffer)
|
|
; D0.W - size of record (data + key)
|
|
; D1.W - index of insert point
|
|
;
|
|
; Output: D0.W - result code
|
|
; 0 = ok
|
|
; -1 = won't fit
|
|
; A1.L - ptr(node buffer) containing new record
|
|
; D1.W - index of new record
|
|
;
|
|
; Called by: BTInsert,ExtRotateLt,RotRecLt
|
|
;__________________________________________________________________________________
|
|
|
|
ExtInsertRec
|
|
MOVEM.L D1-D7/A1-A5,-(SP) ; save regs
|
|
;
|
|
; set up some common stuff
|
|
;
|
|
MOVE.W D0,D7 ; save size of record
|
|
MOVE.W D1,D6 ; save insert index
|
|
MOVE.L A0,D5 ; save ptr to record
|
|
|
|
MOVE.W D1,D0 ; insert index
|
|
JSR ExtGetOffset ;
|
|
MOVE.W D0,D4 ; D4 = insert offset
|
|
|
|
MOVE.W NDNRecs(A1),D0 ; number of keys = last index
|
|
JSR ExtGetOffset ;
|
|
MOVE.L A0,A3 ; A3 = ptr(last offset)
|
|
MOVE.W D0,D3 ; D3 = last offset
|
|
;
|
|
; see if new record will fit
|
|
;
|
|
MOVE.L A3,D1 ; ptr(last offset)
|
|
CLR.L D0 ;
|
|
MOVE.W D3,D0 ; - (last offset + node base)
|
|
ADD.L A1,D0 ;
|
|
SUB.L D0,D1 ; = avail space
|
|
|
|
MOVEQ #2,D0 ; 2 + record size
|
|
ADD.W D7,D0 ; = required size
|
|
|
|
CMP.W D0,D1 ; enough space ?
|
|
BGE.S IRInsert ; yes ->
|
|
|
|
MOVEQ #-1,D0 ; indicate "won't fit"
|
|
BRA.S IRExit ; exit
|
|
;
|
|
; make hole for new record
|
|
;
|
|
IRInsert
|
|
MOVE.L A1,A5 ; A5 = ptr(node buffer)
|
|
|
|
LEA 0(A5,D4.W),A0 ; source = ptr(insert record)
|
|
LEA 0(A0,D7.W),A1 ; dest = source + size
|
|
MOVE.W D3,D0 ; last offset
|
|
SUB.W D4,D0 ; - insert offset = count
|
|
JSR ExtMovRecRt ; make hole for new record
|
|
;
|
|
; adjust offsets for moved records
|
|
;
|
|
MOVE.L A3,A0 ; source ptr = ptr to last offset
|
|
LEA -2(A0),A1 ; dest ptr = source ptr - 2
|
|
MOVE.W NDNRecs(A5),D0 ; offset count =
|
|
SUB.W D6,D0 ; last index - insert index
|
|
MOVE.W D7,D1 ; delta = record size
|
|
JSR ExtMovOffLt ; adjust offsets left
|
|
;
|
|
; move in the new record
|
|
;
|
|
MOVE.L D5,A0 ; source = ptr(record)
|
|
LEA 0(A5,D4.W),A1 ; dest = ptr(insert record)
|
|
MOVE.W D7,D0 ; count = record size
|
|
JSR ExtMovRecLt ; move record in
|
|
|
|
ADDQ.W #1,NDNRecs(A5) ; increment key count
|
|
CLR.W D0 ; result = ok
|
|
|
|
IRExit
|
|
MOVEM.L (SP)+,D1-D7/A1-A5 ; restore regs
|
|
TST.W D0 ; set condition codes
|
|
RTS ; exit ExtInsertRec
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtLocBTCB (Locate BTree Control Block)
|
|
;
|
|
; Function: Locates the BTCB for a BTree file given the refnum.
|
|
;
|
|
; Input: D0.W - file refnum
|
|
;
|
|
; Output: A4.L - pointer to BTCB
|
|
;__________________________________________________________________________________
|
|
|
|
ExtLocBTCB
|
|
;
|
|
; locate BTCB for the file
|
|
;
|
|
MOVEA.L FCBSPtr,A4 ; start of FCBS
|
|
MOVEA.L FCBBTCBptr(A4,D0.W),A4 ; ptr(BTCB)
|
|
RTS ; exit ExtLocBTCB
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtLocRec (Locate Record))
|
|
;
|
|
; Function: Locates the key and data record for a specified BTree record.
|
|
;
|
|
; Input: A1.L - ptr(node buffer)
|
|
; D1.W - record index
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output:
|
|
; A0.L - ptr(key)
|
|
; A1.L - ptr(data record)
|
|
; D1.W - size of record
|
|
;__________________________________________________________________________________
|
|
|
|
ExtLocRec
|
|
MOVEM.L D0/D2-D3,-(SP) ; save registers
|
|
|
|
MOVE.W D1,D3 ; D3 = record index
|
|
|
|
MOVE.W D3,D0 ; locate
|
|
JSR ExtGetRecA ; ...the record
|
|
MOVE.L A0,D2 ; D2 = ptr(record)
|
|
MOVE.W D3,D0 ; locate
|
|
ADDQ #1,D0 ;
|
|
JSR ExtGetRecA ; ...the next record
|
|
MOVE.L A0,D1 ; D1 = ptr(next record)
|
|
|
|
MOVEA.L D2,A0 ; ptr(key) = ptr(record)
|
|
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
|
|
SUB.L D2,D1 ; record size = ptr(next record)
|
|
SUB.L D0,D1 ; - ptr(record) - (adj key length)
|
|
MOVEA.L A0,A1 ; ptr(data record) = ptr(key)
|
|
ADDA.L D0,A1 ; + (adj key length)
|
|
|
|
MOVEM.L (SP)+,D0/D2-D3 ; restore registers
|
|
RTS ; exit ExtLocRec
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtLocTPR (Locate Tree Path Record)
|
|
;
|
|
; Function: Locates the Tree Path Record (TPR) for a given tree level.
|
|
;
|
|
; Input: D0.W - tree level
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output: A0.L - ptr(TPR)
|
|
;__________________________________________________________________________________
|
|
|
|
ExtLocTPR
|
|
SUB.W #1,D0 ; offset
|
|
MULU #LenTPR,D0 ; ...from beg of table
|
|
MOVEA.L BTCVarPtr(A4),A0 ; ptr to BTree buffer
|
|
LEA BTVTPTable(A0,D0.L),A0 ; get ptr(TPR)
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtMovOffLt
|
|
;
|
|
; Function: Move offsets left within a single node.
|
|
;
|
|
; Input: D0.W - number of offsets
|
|
; D1.W - delta amount to be added to each offset
|
|
; A0.L - pointer to source offset
|
|
; A1.L - pointer to destination offset
|
|
;
|
|
; Output: none
|
|
;__________________________________________________________________________________
|
|
|
|
ExtMovOffLt
|
|
MOVEM.L D0-D2/A0-A1,-(SP) ; save regs
|
|
|
|
@1 MOVE.W (A0)+,D2 ; *ptrDst++ = *ptrSrc++ + delta
|
|
ADD.W D1,D2
|
|
MOVE.W D2,(A1)+
|
|
DBF D0,@1
|
|
|
|
BRA.S MovOExit ; return
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtMovOffRt
|
|
;
|
|
; Function: Move offsets right within a single node.
|
|
;
|
|
; Input: D0.W - number of offsets
|
|
; D1.W - delta amount to be added to each offset
|
|
; A0.L - pointer to source offset
|
|
; A1.L - pointer to destination offset
|
|
;
|
|
; Output: none
|
|
;__________________________________________________________________________________
|
|
|
|
ExtMovOffRt
|
|
MOVEM.L D0-D2/A0-A1,-(SP) ; save regs
|
|
|
|
CMPM.W (A0)+,(A1)+ ; preincrement A0, A1 for loop
|
|
@1 MOVE.W -(A0),D2 ; *ptrDst-- = *ptrSrc-- + delta
|
|
ADD.W D1,D2
|
|
MOVE.W D2,-(A1)
|
|
DBF D0,@1
|
|
MovOExit
|
|
MOVEM.L (SP)+,D0-D2/A0-A1 ; restore regs
|
|
RTS
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtMovRecLt
|
|
;
|
|
; Function: Move records left within a single node.
|
|
;
|
|
; Input: D0.W - number of bytes to move
|
|
; A0.L - pointer to source
|
|
; A1.L - pointer to destination
|
|
;
|
|
; Output: none
|
|
;__________________________________________________________________________________
|
|
|
|
ExtMovRecLt
|
|
MOVEM.L D0-D1/A0-A1,-(SP) ; save regs
|
|
|
|
TST.W D0 ; test byte count
|
|
BLE.S MovlExit ; byte count <= 0
|
|
SUBQ.W #1,D0 ; adjust loop index
|
|
|
|
@1 MOVE.B (A0)+,(A1)+ ; move
|
|
DBRA D0,@1 ; ...it
|
|
MovlExit
|
|
MOVEM.L (SP)+,D0-D1/A0-A1 ; restore regs
|
|
RTS ; return
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtMovRecRt
|
|
;
|
|
; Function: Move records right within a single node.
|
|
;
|
|
; Input: D0.W - number of bytes
|
|
; A0.L - pointer to source
|
|
; A1.L - pointer to destination
|
|
;
|
|
; Output: none
|
|
;__________________________________________________________________________________
|
|
|
|
ExtMovRecRt
|
|
MOVEM.L D0-D1/A0-A1,-(SP) ; save regs
|
|
|
|
TST.W D0
|
|
BLE.S MovrExit ; byte count <= 0
|
|
|
|
ADDA.W D0,A0 ; high-address of source block
|
|
ADDA.W D0,A1 ; high-address of dest block
|
|
SUBQ.W #1,D0 ; byte count - 1
|
|
@1 MOVE.B -(A0),-(A1) ; move
|
|
DBRA D0,@1 ; ...it
|
|
MovrExit
|
|
MOVEM.L (SP)+,D0-D1/A0-A1 ; restore regs
|
|
RTS ; return
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtRelNode
|
|
;
|
|
; Function: Releases use of a BTree node obtained by ExtGetNode.
|
|
; Note: this is a temporary interface, it will change for the new
|
|
; cache.
|
|
;
|
|
; Input: A0.L - pointer to node buffer
|
|
; D1.B - RelBlock option flags
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output D0.W - result code
|
|
; 0 = ok
|
|
; -n = error
|
|
;
|
|
; Called by: BTInsert,BTDelete,BTGetRecord,BTSearch,ExtTreeSearch
|
|
;__________________________________________________________________________________
|
|
|
|
ExtRelNode
|
|
|
|
MOVE.L (SP)+,-(A6) ; save return address on A6 stack
|
|
MOVE.L A1,-(A6) ; save registers
|
|
|
|
MOVE.L A0,D0 ; have a node to release? <23Sep85>
|
|
BEQ.S @RNExit ; no -> <23Sep85>
|
|
|
|
IF HFSDebug THEN ; Only check when debugging <24Sep85>
|
|
TST.W NDNRecs(A0) ; empty node? <23Sep85>
|
|
BEQ.S @1 ; yes, skip node check <23Sep85>
|
|
|
|
MOVEA.L A0,A1 ; ***** check out the node ***** <21Sep85>
|
|
BSR ExtChkNode ; <21Sep85>
|
|
BEQ.S @1 ; ok -> <21Sep85>
|
|
_HFSDSErr ; *** HALT *** <24Sep85>
|
|
ENDIF
|
|
|
|
@1 JSR ExtRelBlock ; release the block <SM1>
|
|
|
|
@RNExit
|
|
MOVE.L (A6)+,A1 ; restore registers
|
|
MOVE.L (A6)+,-(SP) ; put return address back on stack
|
|
TST.W D0 ; set up condition codes
|
|
RTS ; exit ExtRelNode
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtSearchNode
|
|
;
|
|
; Function: Searches a BTree node for a specified key. A binary search
|
|
; algorithym is used.
|
|
;
|
|
; Input: A0.L - ptr(search key)
|
|
; A1.L - ptr(node buffer)
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output: D0.W - result code
|
|
; 0 = ok
|
|
; BTnotfound = record not found
|
|
; A1.L - ptr(node buffer)
|
|
; D1.W - index
|
|
; record index if found
|
|
; insert index if not found
|
|
;
|
|
; Called by: BTSearch,ExtTreeSearch
|
|
;__________________________________________________________________________________
|
|
|
|
ExtSearchNode
|
|
MOVEM.L D2-D5/A1-A3,-(SP) ; save regs
|
|
;
|
|
; set up some common stuff
|
|
;
|
|
MOVE.L A0,A3 ; A3 = ptr(search key)
|
|
MOVE.L A1,A2 ; A2 = ptr(node buffer)
|
|
MOVE.L BTCKeyCR(A4),D5 ; D5 = ptr(key compare routine)
|
|
;
|
|
; search node for key using a binary search
|
|
;
|
|
CLR.W D2 ; lower bnd = 0
|
|
MOVE.W NDNRecs(A2),D3 ; upper bnd = number of recs - 1
|
|
SUBQ.W #1,D3
|
|
|
|
CMP.W D3,D2 ; while lower bnd <= upper bnd
|
|
BGT.S SrchExit
|
|
SrchLoop
|
|
MOVE.W D2,D4 ; index = (upper+lower) / 2
|
|
ADD.W D3,D4 ;
|
|
LSR.W #1,D4 ; D4 = new index
|
|
|
|
MOVE.W D4,D0 ; get ptr(trial key)
|
|
MOVE.L A2,A1 ;
|
|
JSR ExtGetRecA ;
|
|
MOVE.L A0,A1 ; A1 = ptr(trial key)
|
|
MOVEA.L A3,A0 ; A0 = ptr(search key)
|
|
|
|
MOVE.L A4,-(SP) ; save A4
|
|
MOVEA.L D5,A4 ; A4 = ptr(key compare routine)
|
|
JSR (A4) ; compare the keys
|
|
MOVE.L (SP)+,A4 ; restore A4
|
|
TST.W D0 ; test result code
|
|
BEQ.S SrchEQ ; search key = trial key ->
|
|
BGT.S SrchGT ; search key > trial key ->
|
|
|
|
SrchLT ; search key < trial key
|
|
MOVE.W D4,D3 ; upper = index - 1
|
|
SUBQ.W #1,D3
|
|
CMP.W D3,D2 ; upper <= lower ?
|
|
BLE.S SrchLoop
|
|
BRA.S SrchExit
|
|
SrchEQ
|
|
CLR.W D0 ; result = FOUND
|
|
BRA.S SrchRet
|
|
SrchGT
|
|
MOVE.W D4,D2 ; lower = index + 1
|
|
ADDQ.W #1,D2
|
|
CMP.W D3,D2 ; lower <= upper ?
|
|
BLE.S SrchLoop
|
|
SrchExit
|
|
MOVE.W D2,D4 ; index = lower
|
|
MOVEQ #BTnotfound,D0 ; result = 'not found' <14Oct85>
|
|
;
|
|
; clean up and exit
|
|
;
|
|
SrchRet
|
|
MOVE.W D4,D1 ; return index in D1
|
|
MOVEM.L (SP)+,D2-D5/A1-A3 ; restore regs
|
|
TST.W D0 ; set up condition codes
|
|
RTS ; exit ExtSearchNode
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtUpdDRec (Update Data Record)
|
|
;
|
|
; Function: Updates the data portion of a BTree record.
|
|
;
|
|
; Input: A0.L - ptr(data record)
|
|
; 0 = create a null record (cleared to zero)
|
|
; D0.W - size of data record
|
|
; A1.L - ptr(node buffer) containing BTree record
|
|
; D1.W - index of BTree record
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output: none
|
|
;__________________________________________________________________________________
|
|
|
|
ExtUpdDRec
|
|
MOVEM.L D0-D1/A0-A2,-(SP) ; save registers
|
|
MOVEA.L A0,A2 ; A2 = ptr(data record)
|
|
|
|
JSR ExtLocRec ; locate data position in BTree record
|
|
|
|
MOVE.L A2,D1 ; ptr(data record)
|
|
BEQ.S @2 ; ptr = 0, clear the record ->
|
|
MOVEA.L D1,A0 ; source = data record
|
|
EXT.L D0 ; move length = record size
|
|
_BlockMove ; move in the data record
|
|
BRA.S UDExit ; all done ->
|
|
|
|
@1 CLR.B (A1)+ ; clear the record
|
|
@2 DBRA D0,@1 ;
|
|
|
|
UDExit
|
|
MOVEM.L (SP)+,D0-D1/A0-A2 ; restore registers
|
|
RTS ; exit ExtUpdDRec
|
|
|
|
|
|
|
|
|
|
|
|
;__________________________________________________________________________________
|
|
;
|
|
; Routine: ExtUpdIKey (Update Index Key)
|
|
;
|
|
; Function: Updates the key portion of an index record. Variable
|
|
; length source keys are padded with $00 to obtain a fixed
|
|
; length index key.
|
|
;
|
|
; Input: A0.L - pointer to source key
|
|
; A1.L - pointer to index record key
|
|
; A4.L - pointer to BTCB
|
|
;
|
|
; Output: A1.L - pointer to updated index record key
|
|
;__________________________________________________________________________________
|
|
|
|
ExtUpdIKey
|
|
MOVEM.L D0-D1/A0-A2,-(SP) ; save regs
|
|
MOVEA.L A0,A2 ; save ptr(source key)
|
|
|
|
MOVE.W BTCKeyLen(A4),D1 ; get max key length
|
|
MOVE.B D1,(A1)+ ; stuff max key length
|
|
MOVEA.L A2,A0 ; ptr(source key)
|
|
MOVEQ #0,D0 ; fixing a bug here <06Jul90>
|
|
MOVE.B (A0)+,D0 ; source key length <06Jul90>
|
|
; EXT.W D0 ; this is bad for D0 >= $80 <06Jul90>
|
|
|
|
SUB.W D0,D1 ; max key length - source key length
|
|
BGE.S @2 ; length ok, decrement before testing ->
|
|
ADD.W D1,D0 ; source > max, use max length
|
|
BRA.S @2 ;
|
|
@1 MOVE.B (A0)+,(A1)+ ; copy next byte
|
|
@2 DBF D0,@1 ;
|
|
|
|
TST.W D1 ; need any null padding?
|
|
BLE.S @5 ; no ->
|
|
BRA.S @4 ; decrement before testing
|
|
@3 CLR.B (A1)+ ; clear next byte in key (null pad)
|
|
@4 DBF D1,@3
|
|
|
|
@5 MOVEM.L (SP)+,D0-D1/A0-A2 ; restore regs
|
|
RTS ; exit ExtUpdIKey
|
|
|
|
END
|
|
|
|
|