mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-27 10:29:32 +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.
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
|
|
|