mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-12-01 02:51:04 +00:00
662 lines
26 KiB
Plaintext
662 lines
26 KiB
Plaintext
;
|
||
; File: DiskInitHFS.a
|
||
;
|
||
; Contains: These routines are used to write a TFS directory onto a volume
|
||
;
|
||
; Written by: Patrick W. Dirks, December 21 1984.
|
||
;
|
||
; Copyright: © 1984-1992 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <6> 2/10/92 JSM Moved this file to DiskInit folder, keeping all the old
|
||
; revisions.
|
||
; <5> 8/30/91 DTY Define has3rdFloppy here since it’s no longer defined in
|
||
; BBSStartup.
|
||
; <4> 6/12/91 LN Removed #includes for private interfaces from public interfaces.
|
||
; Changed #include 'HardwareEqu.a' to 'HardwarePrivateEqu.a'
|
||
; <3> 5/1/90 DDG Removed the temporary conditionals that I added for Sys605.
|
||
; <2> 3/2/90 DDG Added conditionals for Sys605.
|
||
; <1.1> 11/17/89 dba got rid of checks for 64K ROMs
|
||
; <1.0> 11/16/88 CCH Added to EASE.
|
||
; 7/23/87 BB Fixed calculation of allocation block size for volumes sizes
|
||
; which are exact multiples of 32MB.
|
||
; 12/3/86 BB Adjusted maximun clump size to fix rounding error.
|
||
; 11/21/86 BB Modified to force a maximum clump size of 1MB for the catalog
|
||
; and extents files.
|
||
; 12/27/85 EHB Only use low memory default record if new ROMs
|
||
; 8/27/85 EHB Zero defaults for cache sizes (larry does it now)
|
||
; 8/26/85 EHB Added setup of NDNHeight for catalog node
|
||
; 8/12/85 DLD New version for MPW build.
|
||
; 8/9/85 PWD Added setup of record count and first and last node pointers in
|
||
; B*-Tree header
|
||
; 8/8/85 EHB Modified for variable B*-Tree node sizes
|
||
; 7/12/85 EHB Removed setup of DrNxtDirID (field all gone)
|
||
; 7/8/85 EHB Take constants from default record
|
||
; 6/27/85 EHB Crunched extensively
|
||
; 6/25/85 EHB Write spare copy of MDB at end of volume
|
||
; 6/17/85 EHB Converted for use with DiskInit package
|
||
; 5/15/85 PWD Added DrWrCnt field to MDB
|
||
; 5/10/85 PWD Added DrNmRtDirs field to MDB
|
||
; 5/6/85 PWD Changed for new FXM
|
||
; 4/22/85 PWD Added code to special-case drives 1 and 2 in volume sizing
|
||
; 4/17/85 PWD Changed to pick up volume size from Drive Queue Entry
|
||
; 3/17/85 PWD Renamed and moved 'last backup' field.
|
||
; 2/19/85 PWD Removed .Defs for MountVol and UnmountVol; TFSUtil now uses PB
|
||
; interface calls for Mount/Unmount/Eject.
|
||
; 2/11/85 PWD Changed MountVol and UnMountVol to use volume cache for all I/O
|
||
; 2/5/85 PWD Changed MountVol to split volume information over two VCB areas.
|
||
; 1/30/85 PWD Added TFSUnmount
|
||
; 1/29/85 PWD Updated to use word-long AlBlkSize fields
|
||
; 12/21/84 PWD New today.
|
||
;
|
||
|
||
; this code module is stored as a resource of type FMTR = CODE and is called by
|
||
; jumping to it's entry point. It only contains one main routine, and is only loaded
|
||
; by the format package if TFS is present in the system.
|
||
|
||
|
||
;
|
||
; <5> has3rdFloppy is false for both System and ROM builds.
|
||
;
|
||
|
||
if (&type('has3rdFloppy') = 'UNDEFINED') then ; <5>
|
||
has3rdFloppy: equ 0 ; <5>
|
||
endif ; <5>
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
PRINT OFF
|
||
LOAD 'StandardEqu.d'
|
||
INCLUDE 'HardwarePrivateEqu.A'
|
||
INCLUDE 'SonyEqu.A'
|
||
|
||
PRINT ON
|
||
|
||
;----------------------------------------------------------------------------------------------------
|
||
|
||
TFSFMTR PROC EXPORT
|
||
|
||
; A6 offsets. Stack frame established externally
|
||
|
||
UpDatFlg EQU -2 ; (word) used to avoid infinite update problem
|
||
OldPort EQU UpDatFlg-4 ; (long) save port
|
||
DlogResult EQU OldPort-2 ; (word) ModalDialog result
|
||
|
||
theRect EQU DlogResult-8 ; (rect) item rectangle
|
||
theItem EQU theRect-4 ; (long) item handle
|
||
theType EQU theItem-2 ; (word) item type
|
||
itemCount EQU theType-2 ; (word) number of items in list
|
||
saveRect EQU itemCount-8 ; (rect) place to save the old icon's rect <01 Jul 85>
|
||
saveIcon EQU saveRect-4 ; (long) place to save the old icon's handle <26 Jun 85>
|
||
|
||
SideCnt EQU saveIcon-2 ; (word) $0001 or $0002 depending on sides to format <21 Jun 85>
|
||
DQElPtr EQU SideCnt-4 ; (long) drive queue element ptr
|
||
DriveBlks EQU DQElPtr-4 ; (long) drive size in blocks <21 Jun 85>
|
||
StackBuf EQU DriveBlks-512 ; ( 512) large buffer for volname, disk blk
|
||
VolNameBuf EQU StackBuf-32 ; ( 32) temp buffer for volume name <21 Jun 85>
|
||
IOPBlk EQU VolNameBuf-IOVQElSize ; ( 64) parameter blk for I/O calls
|
||
|
||
; NOTE: name is read into VolNameBuf, assumes StackBuf is after to catch overflow chars
|
||
|
||
InitTFSCode
|
||
BRA.S TFSInit ; branch to code <3Dec85>
|
||
;
|
||
; Constant definitions
|
||
;
|
||
VCSize EQU 1 ; Volume cache size
|
||
VBMCSize EQU 1 ; Bitmap cache size
|
||
CtlCSize EQU 4 ; Volume control cache size
|
||
VBMSt EQU 3 ; starting block of volume bit map
|
||
KeyLen EQU 37 ; maximum key length
|
||
|
||
myFmtDefaults ; formatting constants used herein
|
||
|
||
DC.W TSigWord ; Signature word
|
||
DC.L 0 ; allocation block size (0 -> calculate it)
|
||
DC.L 0 ; clump size (0 -> calculate it)
|
||
DC.L NxFreeFN ; next free file number
|
||
DC.L 0 ; B-tree clump size (0 -> calculate it)
|
||
DC.W 0 ; reserved <EHB 27-Aug-85>
|
||
DC.W 0 ; reserved <EHB 27-Aug-85>
|
||
DC.W 0 ; reserved <EHB 27-Aug-85>
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: TFSInit
|
||
;
|
||
; Function: This routine writes an initial TFS volume structure on
|
||
; a selected volume. It is assumed that the disk
|
||
; has already been formatted and verified.
|
||
;
|
||
; Before this routine is called, the stack buffer has been
|
||
; cleared, and the name written into it, and the TagData has
|
||
; been cleared
|
||
;
|
||
; Modification History:
|
||
;
|
||
; 01 AUG 84 BB New today.
|
||
; 12 SEP 84 BB Changed to use TFSEQU.text
|
||
; 18-Dec-84 PWD Updated volume format, integrated into TFS skeleton app.
|
||
; 6-Mar-85 PWD Changed to use extensible B*-Tree structure.
|
||
; 17-Apr-85 PWD Changed to pick up volume size from DQE.
|
||
; 6-May-85 PWD Changed for new FXM: updated MDB layout, changed initialization
|
||
; of extent tree.
|
||
; 17-Jun-85 EHB Modified for new diskInit package.
|
||
; 8-Aug-85 EHB Modified for variable B-Tree node sizes
|
||
; 26-Sep-85 EHB Made changes for >32 Mbyte volumes
|
||
;_________________________________________________________________________________
|
||
;
|
||
;
|
||
; On entry: A3 points to the stack buffer
|
||
;
|
||
; On exit: D0 contains error # (CCR set)
|
||
; A0 trashed
|
||
;
|
||
; Register conventions:
|
||
;
|
||
; A2 points to current position in MDB
|
||
; A3 points to stack buffer
|
||
; A4 points to default constants for formatting
|
||
;
|
||
; D7 Allocation block size
|
||
; D6 Clump size (XT and CT)
|
||
; D5 extent tree size in allocation blocks (XT and CT)
|
||
;_________________________________________________________________________________
|
||
|
||
TFSInit:
|
||
MOVE.L A3,A2 ; use A2 to waltz through MDB
|
||
|
||
LEA myFmtDefaults,A4 ; point to our default constants
|
||
|
||
MOVE.L FmtDefaults,D0 ; are the low-memory constants set up?
|
||
BEQ.S @1 ; => no, we're cool
|
||
MOVE.L D0,A4 ; else get new constants
|
||
@1
|
||
MOVE.W (A4)+,(A2)+ ; set volume signature
|
||
MOVE.L Time,D0 ; get the time
|
||
MOVE.L D0,(A2)+ ; set creation date
|
||
MOVE.L D0,(A2)+ ; set last backup date
|
||
|
||
CLR.L HFSTagData ; make sure HFS tag stuff is NIL <EHB 13Aug85>
|
||
MOVEQ #1,D0 ; default value for system tag and file # <EHB 13Aug85>
|
||
MOVE.L D0,TagData+10 ; set up write sequence number <EHB 13Aug85>
|
||
MOVE.L D0,TagData+2 ; set up default FilNum <EHB 13Aug85>
|
||
|
||
CLR.L (A2)+ ; DrAtrb,DrNmFls = 0
|
||
MOVE.W #VBMSt,(A2)+ ; DrVBMSt = 3
|
||
CLR.W (A2)+ ; DrAllocPtr = 0
|
||
|
||
MOVE.L DriveBlks(A6),D6 ; D6 = volume size in 512-byte blocks <20Jun85>
|
||
|
||
MOVE.L (A4)+,D7 ; D7 = allocation block size in bytes
|
||
BNE.S @2 ; => use default
|
||
|
||
; if specified allocation block size = 0, then calculate based on volume size
|
||
; ABS = 1 + (volSize/64K)
|
||
|
||
MOVE.L D6,D7 ; get volume size in 512-byte blocks
|
||
; SUBQ.L #1,D7 ; if exact block boundary, round down <23Jul87>
|
||
CLR.W D7 ; how many 64K pieces in volume?
|
||
SWAP D7 ; get into low word
|
||
ADDQ.W #1,D7 ; now round back up <11Dec85>
|
||
ASL.L #8,D7 ; Multiply by 512 for size in bytes
|
||
ADD.L D7,D7 ; D7 = allocation block size in bytes
|
||
|
||
@2 MOVE.L D6,D0 ; get volume size in 512-byte blocks
|
||
ASL.L #8,D0 ; Multiply by 256 towards size in bytes
|
||
ADD.L D0,D0 ; D0 = volume size in bytes
|
||
|
||
; After computing the number of allocation blocks to be mapped on the volume, the
|
||
; bitmap size (in 512 byte sectors) is computed from:
|
||
;
|
||
; Volume Size (Al. Blks) = 4096 * Bitmap Size (sectors) +
|
||
; Remainder to be mapped (Al. Blks)
|
||
;
|
||
; Since the Bitmap Size (the quotient) will not be mapped itself, if the remainder
|
||
; is less than or equal to the quotient after conversion to allocation blocks
|
||
; (i.e. if the number of allocation blocks occupied by the bitmap is greater than
|
||
; or equal to the number of as yet unmapped allocation blocks), everything will
|
||
; work fine. Otherwise, an additional sector will have to be allocated to
|
||
; the bitmap for the remaining allocation blocks.
|
||
|
||
DIVU D7,D0 ; divide to get volsize in alloc. blocks
|
||
AND.L #$FFFF,D0 ; ignore remainder <11Dec85>
|
||
DIVU #4096,D0 ; divide by 512*8 to get bitmap size
|
||
MOVEQ #0,D4 ; Clear high word of D4 (will contain DrAlBlSt)
|
||
MOVE.W D0,D4 ; Quotient after division (bitmap size)
|
||
|
||
SWAP D0 ; get remainder <11Dec85>
|
||
TST.W D0 ; was there one? <11Dec85>
|
||
BEQ.S @25 ; => no <11Dec85>
|
||
ADDQ.L #1,D4 ; else save one more for bitmap <11Dec85>
|
||
|
||
@25: ADDQ.W #3,D4 ; Throw in boot blocks & MDB
|
||
; D4 = DrAlBlSt
|
||
MOVE.L D6,D2 ; Pick up volume size in 512-byte blocks <20Jun85>
|
||
SUB.L D4,D2 ; Adjust for 'lost' space
|
||
LSL.L #8,D2 ; Multiply by 256
|
||
ADD.L D2,D2 ; and again by 2 to get byte count
|
||
DIVU D7,D2 ; Compute allocation block count
|
||
SUBQ #2,D2 ; Save last block for MDB copy (Like MFS)
|
||
MOVE.W D2,(A2)+ ; set DrNmAlBlks (true volume size in alloc. blocks)
|
||
; D2 = free alloc blocks in D2 (so far)
|
||
MOVE.L D7,(A2)+ ; set DrAlBlkSiz
|
||
|
||
MOVE.L (A4)+,D0 ; get clump size <EHB 26Sep85>
|
||
BNE.S @27 ; => pre-defined, use it <EHB 26Sep85>
|
||
MOVE.L D7,D0 ; else use 4*allocation block size <EHB 26Sep85>
|
||
LSL.L #2,D0 ; <EHB 26Sep85>
|
||
@27: MOVE.L D0,(A2)+ ; set DrClpSiz (file clump size) <EHB 26Sep85>
|
||
|
||
MOVE.W D4,(A2)+ ; D4 = DrAlBlSt= first mapped block on disk
|
||
MOVE.L (A4)+,(A2)+ ; set next free file number
|
||
|
||
; skip over name (already set) and a bunch of zero fields
|
||
|
||
; The XT and CT clump size is computed by dividing the original number of BLOCKS
|
||
; on the volume by 128, rounding down, and multiplying the result out to bytes again.
|
||
|
||
MOVE.L (A4)+,D0 ; examine default B-tree clump size
|
||
BEQ.S @22 ; => calculate it ourselves
|
||
MOVE.L D0,D6 ; else get B-tree clump size in bytes
|
||
BRA.S @26 ; => and go set up extent and catalog
|
||
|
||
@22 LSR.L #7,D6 ; 'Divide' by 128 to get XT & CT clump size <20Jun85>
|
||
BNE.S @23 ; If already > 0, we're all set
|
||
MOVEQ #1,D6
|
||
@23 ASL.L #8,D6 ; Multiply by 256 towards size in bytes
|
||
ADD.L D6,D6 ; D6 = XT and CT clump size in bytes
|
||
|
||
@26 MOVE.L #$100000,D0 ; max clump size is 1MB <21Nov86>
|
||
SUB.L D7,D0 ; - alloc block size (to allow for rounding) <03Dec86>
|
||
CMP.L D0,D6 ; clump size > max? <21Nov86>
|
||
BLE.S @28 ; ... no, use what we have <21Nov86>
|
||
MOVE.L D0,D6 ; ... yes, use max size <21Nov86>
|
||
|
||
@28 LEA DrVCSize(A3),A2 ; point to volume cache size
|
||
MOVE.L (A4)+,(A2)+ ; set volume cache size, volume bit map cache size
|
||
MOVE.W (A4)+,(A2)+ ; set extent and catalog B*tree cache size
|
||
|
||
LEA DrXTFlSize(A3),A2 ; Point to extent tree size
|
||
MOVE.L D6,D5 ; get clump size (XT and CT)
|
||
DIVU D7,D5 ; divide by allocation block size
|
||
SWAP D5 ; get remainder in low word
|
||
ADD.L #$FFFF,D5 ; round up high word
|
||
SWAP D5 ; D5.W = # of allocation blocks
|
||
|
||
SUB.W D5,D2 ; subtract size of extent tree
|
||
MOVE.W D5,D0 ; get # of allocation blocks
|
||
MULU D7,D0 ; get size in bytes
|
||
MOVE.L D0,(A2)+ ; save in DrXTFlSize
|
||
CLR.W (A2)+ ; start block of extent tree = 0
|
||
MOVE.W D5,(A2)+ ; length in allocation blocks
|
||
ADDQ #8,A2 ; next 2 records are 0
|
||
|
||
SUB.W D5,D2 ; subtract size of catalog tree
|
||
MOVE.W D2,DrFreeBks(A3) ; and save as number of free blocks
|
||
MOVE.L D0,(A2)+ ; DrCTFlSize in bytes
|
||
MOVE.W D5,(A2)+ ; start = end of first extent
|
||
MOVE.W D5,(A2)+ ; length = same as first extent record
|
||
|
||
LEA DrXTClpSiz(A3),A2 ; point to extent tree clump size
|
||
MOVE.L D0,(A2)+ ; Set extent tree clump size (rounded byte size)
|
||
MOVE.L D0,(A2)+ ; Set catalog tree clump size
|
||
MOVE.L D0,D6 ; and save for below
|
||
|
||
MOVEQ #2,D0 ; get initial write sequence number
|
||
MOVE.L D0,DrWrCnt(A3) ; and write it to MDB
|
||
|
||
; write master block to disk
|
||
|
||
MOVEQ #2,D1 ; block # of MDB <21Jun85>
|
||
MOVEQ #1,D2 ; 1 block long
|
||
MOVE.L D1,D3 ; tag sequence number (0 - 1st block) <21Jun85>
|
||
BSR BlkWrite ; write it to disk
|
||
BNE @95 ; Give up easily
|
||
|
||
; place a spare copy at the end of the volume
|
||
|
||
MOVE.L DriveBlks(A6),D1 ; get # of blocks on volume <25 Jun 85>
|
||
SUBQ.L #2,D1 ; disk size in blocks -2 <25 Jun 85>
|
||
MOVEQ #1,D2 ; 1 block long <25 Jun 85>
|
||
MOVE.L D1,D3 ; tag sequence number (0 - 1st block) <25 Jun 85>
|
||
BSR BlkWrite ; write it to disk <25 Jun 85>
|
||
BNE @95 ; punt on error <25 Jun 85>
|
||
|
||
; save some data from the MDB for later use
|
||
; D6 = clump size (XT and CT)
|
||
; D4 = DrAlBlSt
|
||
; #VBMSt = DrVBMSt(A3)
|
||
|
||
MOVEQ #0,D0 ; Clear top half of D0.L
|
||
MOVE.W DrNmAlBlks(A3),D0 ; Get total volume size (in alloc. blocks)
|
||
SUB.W DrFreeBks(A3),D0 ; Subtract out free blocks to get blocks taken
|
||
|
||
; set up Volume Bitmap
|
||
|
||
BSR ClrStkBuf ; clear the buffer first
|
||
MOVE.L A3,A1 ; and get pointer to the buffer
|
||
|
||
DIVU #8,D0 ; get # of $FF bytes and # of bits left
|
||
CLR.L D1 ; put # of $FF bytes
|
||
MOVE.W D0,D1 ; ... in D1
|
||
CLR.W D0 ; put # of bits left
|
||
SWAP D0 ; ... in low half of D0
|
||
|
||
TST.W D1 ; Any whole bytes to set?
|
||
BEQ @35 ; Nope - don't bother
|
||
SUBQ #1,D1 ;
|
||
@30 ST (A1)+ ; True = FF
|
||
DBRA D1,@30 ; ... in the buffer
|
||
|
||
@35 MOVE.B #$80,D2 ; assume 1 bit left
|
||
SUBQ #1,D0 ; get shift count ( # bits left - 1)
|
||
BMI @50 ; no bits to set
|
||
BEQ @40 ; 1 bit, already set
|
||
ASR.B D0,D2 ; 2-7 bits, shift them into D2
|
||
@40 MOVE.B D2,(A1) ; update the buffer
|
||
|
||
@50:
|
||
|
||
; write Bitmap to disk
|
||
|
||
MOVEQ #VBMSt,D1 ; get DrVBMSt as a long
|
||
MOVEQ #1,D2 ; 1 block long
|
||
MOVE.L D1,D3 ; tag sequence number (0 - 1st block) <21Jun85>
|
||
BSR BlkWrite ; write it
|
||
BNE @95 ; Give up without a write
|
||
|
||
BSR ClrStkBuf ; clear buffer for remaining blocks
|
||
MOVEQ #0,D2 ; <21Jun85>
|
||
MOVE.W D4,D2 ; get DrAlBlSt
|
||
SUBQ.W #VBMSt+1,D2 ; subtract drVBMSt+1 to get remaining blocks in bitmap
|
||
BEQ.S @60 ; none left
|
||
BSR BlkWrite ; write them out
|
||
BNE @95 ; keep going only while the going's good
|
||
@60:
|
||
;
|
||
; set up File extents B*-Tree
|
||
;
|
||
; set up tag data:
|
||
;
|
||
ADDQ.W #2,TagData+4 ; FilNum = 3 <EHB 13Aug85>
|
||
;
|
||
MOVEQ #0,D1 ; make block num a long <EHB 26Sep85>
|
||
MOVE.W D4,D1 ; start at first mapped block (DrAlBlSt)
|
||
MOVE.L D6,D2 ; Get extent tree clump size in bytes
|
||
MOVEQ #0,D0 ; No records in extent tree
|
||
LSR.L #8,D2 ; 'Divide' by 256
|
||
LSR.L #1,D2 ; and again by 2 to get size in blocks
|
||
MOVE.W #7,D3 ; Max. key length
|
||
BSR SetupBTree ; Set up a B*-Tree skeleton (leaves buffer clear)
|
||
BNE @95 ; Quit at the slightest hint of trouble
|
||
|
||
; Set up the file catalog B*-Tree:
|
||
|
||
; set up tag data:
|
||
|
||
ADDQ.W #1,TagData+4 ; FilNum = 4
|
||
|
||
MOVEQ #2,D0 ; There'll be 2 records in the catalog
|
||
MOVEQ #0,D1 ; make block num a long <EHB 26Sep85>
|
||
MOVE.W D4,D1 ; get first block (DrAlBlSt)
|
||
MULU D7,D5 ; Get clump size in bytes <PWD 26Sep85>
|
||
LSR.L #8,D5 ; 'divide' by 256 <PWD 26Sep85>
|
||
LSR.L #1,D5 ; and again by 2 to get size in phys. blocks<PWD 26Sep85>
|
||
ADD.L D5,D1 ; add in size in allocation blocks
|
||
MOVE.L D6,D2 ; Get catalog tree clump size (bytes)
|
||
LSR.L #8,D2 ; 'Divide' by 256
|
||
LSR.L #1,D2 ; and again by 2 to get size in blocks
|
||
MOVEQ #KeyLen,D3 ; Max. key length
|
||
BSR SetupBTree ; Set up a B*-Tree skeleton (leaves buffer clear)
|
||
BNE @95 ; Give up readily
|
||
;
|
||
; Set up the first leaf node in the tree:
|
||
|
||
; First set up the node descriptor (most of it zeros)...
|
||
|
||
ST NdType(A3) ; Node type (True = $FF) - leaf node <EHB 8Aug85>
|
||
MOVE.W #2,NdNRecs(A3) ; 2 records in node. <EHB 8Aug85>
|
||
MOVE.B #1,NDNHeight(A3) ; set node height to one for node 2 <EHB 26Sep85>
|
||
|
||
; The first record is the root directory CNode, <1>'Root':
|
||
|
||
; point to it and stuff an offset to it
|
||
|
||
LEA lenND(A3),A1 ; Point to the first key record <21Jun85>
|
||
MOVEQ #-2,D1 ; offset from end of node for offset <EHB 8Aug85>
|
||
BSR.S SetOffset ; set offset to next record <EHB 8Aug85>
|
||
|
||
; stuff the key record. First figure out the length of the key record
|
||
|
||
LEA VolNameBuf(A6),A0 ; Point to volume name <21Jun85>
|
||
MOVEQ #1,D0 ; Clear top 3 bytes + 1 for length byte <21Jun85>
|
||
ADD.B (A0),D0 ; D0 = length + 1 for blockMove <21Jun85>
|
||
MOVE.L D0,D2 ; keep rounded length in D2 <EHB 8Aug85>
|
||
ADDQ #1,D2 ; make it even <EHB 8Aug85>
|
||
BCLR #0,D2 ; by adding one and rounding <EHB 8Aug85>
|
||
MOVE.B D2,(A1) ; store key length <21Jun85>
|
||
ADDQ.B #ckrCName-1,(A1)+ ; as nameLen+bytes before name -1 <EHB 8Aug85>
|
||
CLR.B (A1)+ ; clear filler byte <EHB 8Aug85>
|
||
MOVEQ #FSRtParID,D1 ; Parent ID of root (1) <21Jun85>
|
||
MOVE.L D1,(A1)+ ; DirID in key <21Jun85>
|
||
|
||
_BlockMove ; Put the volume name as the CName <21Jun85>
|
||
ADD D2,A1 ; Advance beyond volume name <21Jun85>
|
||
|
||
; Directory CNode:
|
||
|
||
MOVE.W #$0100,(A1)+ ; Data record type (directory CNode) <21Jun85>
|
||
CLR.L (A1)+ ; Attributes/flag word & valence word <21Jun85>
|
||
|
||
MOVEQ #FSRtDirID,D1 ; Root node's directory ID is 2 <21Jun85>
|
||
MOVE.L D1,(A1)+ ; DirID <21Jun85>
|
||
MOVE.L Time,D1 ; Current date and time <21Jun85>
|
||
MOVE.L D1,(A1)+ ; Creation date time <21Jun85>
|
||
MOVE.L D1,(A1)+ ; Date and time last modified <21Jun85>
|
||
ADD.W #(lendir-dirBkDat),A1 ; bump pointer to end of record <EHB 8Aug85>
|
||
|
||
; The second record in the catalog is the root thread record: key is <2>''
|
||
|
||
; first stuff an offset to this record
|
||
|
||
MOVEQ #-4,D1 ; get offset to offset <EHB 8Aug85>
|
||
BSR.S SetOffset ; and set the offset <EHB 8Aug85>
|
||
|
||
; then stuff the record
|
||
|
||
MOVE.W #$0700,(A1)+ ; Key length = 7. <21Jun85>
|
||
MOVEQ #FSRtDirID,D1 ; get DirID <EHB 9Aug85>
|
||
MOVE.L D1,(A1)+ ; DirID in key <EHB 9Aug85>
|
||
CLR.W (A1)+ ; CName string (null) <21Jun85>
|
||
;
|
||
; Thread record:
|
||
;
|
||
MOVE.W #$0300,(A1)+ ; Record type is thread <21Jun85>
|
||
ADDQ #8,A1 ; skip over reserved bytes <EHB 8Aug85>
|
||
MOVEQ #FSRtParID,D1 ; Root's parent ID <21Jun85>
|
||
MOVE.L D1,(A1)+ ; <21Jun85>
|
||
|
||
; A0 still points to the name, D2 still contains the padded length
|
||
|
||
MOVEQ #1,D0 ; Clear top 3 bytes + 1 for length byte <21Jun85>
|
||
ADD.B (A0),D0 ; D0 = length + 1 for blockMove <21Jun85>
|
||
_BlockMove ; Copy in the volume name <21Jun85>
|
||
ADD.W #CMMaxCName+1,A1 ; make name max size <EHB 12Aug85>
|
||
|
||
; and stuff offset to empty record
|
||
|
||
MOVEQ #-6,D1 ; get the offset to the offset <EHB 8Aug85>
|
||
BSR.S SetOffset ; set the offset to the empty record <EHB 8Aug85>
|
||
|
||
; Write the node out:
|
||
|
||
MOVEQ #0,D1 ; make block num a long <EHB 26Sep85>
|
||
MOVE.W D4,D1 ; DrStAlBl + size in allocation blocks
|
||
ADD.L D5,D1 ; is starting block number
|
||
ADDQ.L #1,D1 ; Advance beyond header block
|
||
MOVEQ #1,D2 ; Write just one block <21Jun85>
|
||
MOVEQ #1,D3 ; Tag sequence number <21Jun85>
|
||
BSR.S BlkWrite ; Write the block
|
||
BNE.S @95 ; Punt on errors
|
||
;
|
||
; clean up and return:
|
||
;
|
||
MOVEQ #0,D0 ; the sweet smell of success...
|
||
@95: RTS ; and return
|
||
|
||
|
||
;------------------------
|
||
; SetOffset places an offset to a record into the node offset table
|
||
;
|
||
; Input: A1 - pointer to beginning of next record
|
||
; A3 - pointer to beginning of node
|
||
; D1 - offset to offset
|
||
;
|
||
; Output: D0,D1 - trashed
|
||
|
||
SetOffset
|
||
MOVE.L A1,D0 ; calculate offset to next record <EHB 8Aug85>
|
||
SUB.L A3,D0 ; from beginning of block <EHB 8Aug85>
|
||
ADD.W #BTNodeSize,D1 ; offset from beginning of node <EHB 8Aug85>
|
||
MOVE.W D0,0(A3,D1) ; stuff the offset <EHB 8Aug85>
|
||
RTS
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; BlkWrite (Block Write) subroutine
|
||
;
|
||
; Input: D1 - starting block number (long)
|
||
; D2 - block count (long)
|
||
; D3 - starting tag sequence number
|
||
; A3 - Pointer to buffer to be written (StackBuf)
|
||
;
|
||
; Output: D0 - error code
|
||
; D1 - ending block number + 1
|
||
; D3 - ending tag sequence number +1
|
||
;_______________________________________________________________________
|
||
|
||
BlkWrite MOVEM.L D2/D4/A0-A2,-(SP) ; save regs
|
||
|
||
LEA IOPBlk(A6),A0 ; point to general I/O param block
|
||
LEA IODrvNum(A0),A2 ; point to first param to set up
|
||
MOVE.L DQElPtr(A6),A1 ; point to drive queue element <20Jun85>
|
||
MOVE.L DQDrive(A1),(A2)+ ; set drive number, refNum
|
||
ADDQ #6,A2 ; point to IOBuffer
|
||
MOVE.L A3,(A2)+ ; IOBuffer = stackBuf
|
||
MOVE.L #512,(A2)+ ; byte count (1 block)
|
||
CLR.L (A2)+ ; skip over IONumDone
|
||
MOVE.W #1,(A2)+ ; position mode 1 (from disk start)
|
||
BRA.S @2 ; make count (D2) 0 based
|
||
|
||
@1 MOVE.L D1,D4 ; block number <PWD 9Aug85>
|
||
LSL.L #8,D4 ; ...x 512
|
||
ADD.L D4,D4 ;
|
||
MOVE.L D4,(A2) ; ... gives disk address in bytes
|
||
MOVE.W D3,TagData+8 ; set file sequence number <EHB 13Aug85>
|
||
_Write ; write one block
|
||
BNE @3 ; exit if error
|
||
|
||
ADDQ.L #1,D1 ; increment block number
|
||
ADDQ.L #1,D3 ; ... and tag sequence number
|
||
@2 SUBQ.L #1,D2 ; do next block
|
||
BGE.S @1 ; loop until -1
|
||
|
||
@3 MOVEM.L (SP)+,D2/D4/A0-A2 ; restore regs
|
||
TST.W D0 ; Set condition codes for return
|
||
RTS
|
||
|
||
EJECT
|
||
;_______________________________________________________________________
|
||
;
|
||
; SetupBTree subroutine
|
||
;
|
||
; Input: D0 - Number of records in first node (long)
|
||
; D1 - starting block number
|
||
; D2 - block count (file size)
|
||
; D3 - Max. key length
|
||
; D4 - drive number (1=internal, 2=exernal)
|
||
; A3 - pointer to stack buffer
|
||
;
|
||
; Output: D0 - error code
|
||
;
|
||
; NOTE: This subroutine leaves the buffer completely cleared
|
||
;_______________________________________________________________________
|
||
|
||
SetupBTree:
|
||
|
||
MOVEM.L D2/D5/A2,-(SP) ; Stash regs for later use
|
||
BSR ClrStkBuf ; Empty the block buffer
|
||
MOVE.W #$8000,D5 ; mark header node as used
|
||
|
||
; Write the B*-Tree header node:
|
||
|
||
; Start with the node descriptor, which is mostly zeros...
|
||
|
||
MOVE.B #NDHdrNode,NDType(A3) ; This node contains the B*-Tree header <EHB 8Aug85>
|
||
MOVE.W #3,NDNRecs(A3) ; There are three records (header & map & user) <EHB 8Aug85>
|
||
MOVE.L D2,lenND+BTHNNodes(A3) ; set total number of nodes (before trashing D2) <EHB 8Aug85>
|
||
|
||
MOVE.L D0,lenND+BTHNRecs(A3) ; Set total number of data records <PWD 9Aug85>
|
||
BEQ @10 ; No records in B*-Tree yet, so header and bitmap are OK<PWD 9Aug85>
|
||
|
||
MOVE.W #$C000,D5 ; otherwise, mark the second node as used too
|
||
SUBQ.L #1,D2 ; Take out first block (to be written) (for below)
|
||
LEA lenND(A3),A2 ; get pointer to BTree Header
|
||
ADDQ.W #1,(A2)+ ; BTHDepth = 1 = Tree depth for empty tree (default = 0)
|
||
ADDQ.L #1,(A2)+ ; BTRoot = 1 = Root node of empty tree (default = 0)
|
||
ADDQ.L #4,A2 ; Skip BTHNRecs field <PWD 9Aug85>
|
||
ADDQ.L #1,(A2)+ ; BTHFNode = 1 <PWD 9Aug85>
|
||
ADDQ.L #1,(A2)+ ; BTHLNode = 1 <PWD 9Aug85>
|
||
|
||
@10 LEA lenND+BTHNodeSize(A3),A2 ; get pointer to buffer <EHB 9Aug85>
|
||
MOVE.W #512,(A2)+ ; BTHNodeSize = Node size
|
||
MOVE.W D3,(A2)+ ; BTHKeyLen = Max. key length
|
||
ADDQ #4,A2 ; BTHNNodes (long) already set <EHB 9Aug85>
|
||
SUBQ.L #1,D2 ; Take out 1 header node
|
||
MOVE.L D2,(A2)+ ; BTHFree = Number of free nodes
|
||
|
||
; Now for the bitmap record:
|
||
|
||
@30 LEA lenND+lenBTH+128(A3),A2 ; point to the allocation map <EHB 8Aug85>
|
||
MOVE.W D5,(A2) ; D5 contains the used bits for the allocation map <EHB 8Aug85>
|
||
|
||
; Now place offsets to the records at the end of the node
|
||
|
||
LEA BTNodeSize-8(A3),A2 ; put 4 offsets at end of node <EHB 8Aug85>
|
||
MOVE.W #lenND+lenBTH+128+256,(A2)+ ; pointer to free space <EHB 8Aug85>
|
||
MOVE.W #lenND+lenBTH+128,(A2)+ ; pointer to alloc map (256 bytes) <EHB 8Aug85>
|
||
MOVE.W #lenND+lenBTH,(A2)+ ; pointer to user space (128 bytes) <EHB 8Aug85>
|
||
MOVE.W #lenND,(A2) ; and pointer to BTH (104 bytes) <EHB 8Aug85>
|
||
|
||
MOVEQ #1,D2 ; Write just one block at a time
|
||
MOVEQ #0,D3 ; Clear tag sequence number for first block
|
||
BSR BlkWrite ; Write the header block
|
||
BNE @95 ; Surrender to the slightest opposition
|
||
|
||
; Write the remaining blocks just to set their tags:
|
||
|
||
MOVE.L (SP),D2 ; Retrieve full size (old D2)
|
||
SUBQ.W #1,D2 ; Subtract header block just written
|
||
BSR.S ClrStkBuf ; Zero it out completely
|
||
BSR BlkWrite ; Write rest of B*-Tree file
|
||
@95: MOVEM.L (SP)+,D2/D5/A2 ; Restore regs
|
||
TST.W D0 ; Set condition codes for return
|
||
RTS ; And call it a day.
|
||
|
||
|
||
ClrStkBuf MOVEM.L D0/A0,-(SP) ; save regs
|
||
LEA StackBuf(A6),A0 ; get address
|
||
MOVEQ #(512/4)-1,D0 ; get number of longs
|
||
|
||
ClrBuf CLR.L (A0)+ ;
|
||
DBRA D0,ClrBuf
|
||
MOVEM.L (SP)+,D0/A0 ; restore regs
|
||
RTS
|
||
|
||
|
||
END
|
||
|