From 371780b11b30be11ca32d785ef19f8562843c560 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sat, 17 Jul 2021 00:21:31 -0400 Subject: [PATCH] . --- bootblock.aii | 171 ++++++++++++++++++++++++++++++++++++++++++++ hfs.aii | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 364 insertions(+) create mode 100644 bootblock.aii create mode 100644 hfs.aii diff --git a/bootblock.aii b/bootblock.aii new file mode 100644 index 0000000..9729c75 --- /dev/null +++ b/bootblock.aii @@ -0,0 +1,171 @@ + + include 'hfs.aii' + +boot proc + + stz offset + lda #2 + jsr read_block + + + endp + +read_block proc + ; input + ; a = hfs block # + ; will be adjusted for allocation block offset + ; + clc + adc offset + sta block + phx + phy + + ply + plx + rts + endp + +findit proc +; +; assumes 512-byte blocks (max size = ....?) +; +; wait a minute... max 65535 blocks, therefore high word of allocation block, etc, always 0. +; + +; +; search for a file named ! in the root directory. +; ! is ascii char $21 so it should sort early. +; +; + lda header+drAlBlSt + xba + sta offset + + lda header+drCTExtRec ; 1st allocation block + xba + sta cat_extents + lda header+drCTExtRec+2 ; # of allocation blocks + xba + sta cat_extents+2 + ; + ; need to do all 3? + ; + +; lda offset +; clc +; adc cat_extents + lda cat_extents + jsr read_block + + ; + ; block should be a btree header block. find the first leaf node. + ; + lda block+$18 + xba + sta leaf+2 + lda block+$18+2 + xba + sta leaf + ; + ; assert leaf < # allocated lbocks? + ; + ;lda leaf + jsr read_block + + lda block+$a ; # of records + xba +; asl a ; x 2 +; sec +; sbc #512 +; eor #-1 +; inc a +; adc #-513 ; carry will be clear. +1 to avoid inc +; eor #-1 + sta count + beq advance + +again + ldx #512-2 ; last entry +@loop + lda block,x + tay + lda block+2,y ; parent id + bne notfound + lda block+4,y + xba + cmp #2 + blt @next + beq @name + bge notfound +@name ; name is a p-string. + lda block+6+1,y + and #$ff + cmp #'!' + blt @next + beq @name2 + bge notfound +@name2 lda block+6,y + cmp #$2101 + bne notfound + brl found +@next dex + dex + dec count + bne @loop +advance ; next block! + lda block+2 + beq notfound + xba + jsr read_block + bra again + +notfound + brk $ea + +found + ; y = offset in block + ; + ; only works with contiguous files.... + ; first block? + + ; assume < 65535 bytes :) + lda block+filPyLen+2,y +; xba + lsr a ; >>9 since already xba + and #%01111111 + beq notfound + sta count + lda block+filExtRec,y + xba + sta extent + lda block+filExtRec+2,y + xba + sta extent+2 + + ; now load the blocks and + lda #$2000 + sta dest + lda extent + clc + adc offset + sta block +@loop + jsr read_block2 + inc block + lda #512 + clc + adc dest + sta dest + dec count + bne @loop + + jmp $2000 ; kiss of life. + + + endp + + + + + end \ No newline at end of file diff --git a/hfs.aii b/hfs.aii new file mode 100644 index 0000000..100c656 --- /dev/null +++ b/hfs.aii @@ -0,0 +1,193 @@ +; borrowed from HFSVolumes.a + + +Str31 RECORD 0 +elements ds.b 32 +sizeof EQU * ; size: $20 (32) + ENDR + + +Str27 RECORD 0 +elements ds.b 28 +sizeof EQU * ; size: $1C (28) + ENDR + +; +; extents +; + +kHFSExtentDensity EQU 3 + +; HFS extent descriptor +HFSExtentDescriptor RECORD 0 +startBlock ds.w 1 ; offset: $0 (0) ; first allocation block +blockCount ds.w 1 ; offset: $2 (2) ; number of allocation blocks +sizeof EQU * ; size: $4 (4) + ENDR + + +; HFS extent record +HFSExtentRecord RECORD 0 +elements ds.b 3*HFSExtentDescriptor.sizeof +sizeof EQU * ; size: $C (12) + ENDR + + +; +; catalog +; + +kHFSRootParentID EQU 1 ; Parent ID of the root folder +kHFSRootFolderID EQU 2 ; Folder ID of the root folder +kHFSExtentsFileID EQU 3 ; File ID of the extents file +kHFSCatalogFileID EQU 4 ; File ID of the catalog file +kHFSBadBlockFileID EQU 5 ; File ID of the bad allocation block file +kHFSAllocationFileID EQU 6 ; File ID of the allocation file (HFS Plus only) +kHFSStartupFileID EQU 7 ; File ID of the startup file (HFS Plus only) +kHFSAttributesFileID EQU 8 ; File ID of the attribute file (HFS Plus only) +kHFSBogusExtentFileID EQU 15 ; Used for exchanging extents in extents file +kHFSFirstUserCatalogNodeID EQU 16 + +kHFSFolderRecord EQU $01 ; Folder record +kHFSFileRecord EQU $02 ; File record +kHFSFolderThreadRecord EQU $03 ; Folder thread record +kHFSFileThreadRecord EQU $04 ; File thread record + + +; HFS catalog key +HFSCatalogKey RECORD 0 +keyLength ds.b 1 ; offset: $0 (0) ; key length (in bytes) +reserved ds.b 1 ; offset: $1 (1) ; reserved (set to zero) +parentID ds.l 1 ; offset: $2 (2) ; parent folder ID +nodeName ds Str31 ; offset: $6 (6) ; catalog node name +sizeof EQU * ; size: $26 (38) + ENDR + + + +; HFS catalog folder record - 70 bytes +HFSCatalogFolder RECORD 0 +recordType ds.b 1 ; offset: $0 (0) ; record type + ds.b 1 ; reserved +flags ds.w 1 ; offset: $2 (2) ; folder flags +valence ds.w 1 ; offset: $4 (4) ; folder valence +folderID ds.l 1 ; offset: $6 (6) ; folder ID +createDate ds.l 1 ; offset: $A (10) ; date and time of creation +modifyDate ds.l 1 ; offset: $E (14) ; date and time of last modification +backupDate ds.l 1 ; offset: $12 (18) ; date and time of last backup +userInfo ds.b 16 ; offset: $16 (22) ; Finder information +finderInfo ds.b 16 ; offset: $26 (38) ; additional Finder information +reserved ds.l 4 ; offset: $36 (54) ; reserved - set to zero +sizeof EQU * ; size: $46 (70) + ENDR + +; HFS catalog file record - 102 bytes +HFSCatalogFile RECORD 0 +recordType ds.w 1 ; offset: $0 (0) ; record type +flags ds.b 1 ; offset: $2 (2) ; file flags +fileType ds.b 1 ; offset: $3 (3) ; file type (unused ?) +userInfo ds.b 16 ; offset: $4 (4) ; Finder information +fileID ds.l 1 ; offset: $14 (20) ; file ID +dataStartBlock ds.w 1 ; offset: $18 (24) ; not used - set to zero +dataLogicalSize ds.l 1 ; offset: $1A (26) ; logical EOF of data fork +dataPhysicalSize ds.l 1 ; offset: $1E (30) ; physical EOF of data fork +rsrcStartBlock ds.w 1 ; offset: $22 (34) ; not used - set to zero +rsrcLogicalSize ds.l 1 ; offset: $24 (36) ; logical EOF of resource fork +rsrcPhysicalSize ds.l 1 ; offset: $28 (40) ; physical EOF of resource fork +createDate ds.l 1 ; offset: $2C (44) ; date and time of creation +modifyDate ds.l 1 ; offset: $30 (48) ; date and time of last modification +backupDate ds.l 1 ; offset: $34 (52) ; date and time of last backup +finderInfo ds.b 16 ; offset: $38 (56) ; additional Finder information +clumpSize ds.w 1 ; offset: $48 (72) ; file clump size (not used) +dataExtents ds HFSExtentRecord ; offset: $4A (74) ; first data fork extent record +rsrcExtents ds HFSExtentRecord ; offset: $56 (86) ; first resource fork extent record +reserved ds.l 1 ; offset: $62 (98) ; reserved - set to zero +sizeof EQU * ; size: $66 (102) + ENDR + +; HFS catalog thread record - 46 bytes +HFSCatalogThread RECORD 0 +recordType ds.w 1 ; offset: $0 (0) ; record type +reserved ds.l 2 ; offset: $2 (2) ; reserved - set to zero +parentID ds.l 1 ; offset: $A (10) ; parent ID for this catalog node +nodeName ds Str31 ; offset: $E (14) ; name of this catalog node +sizeof EQU * ; size: $2E (46) + ENDR + + +; Master Directory Block (HFS only) - 162 bytes +; Stored at sector #2 (3rd sector) +HFSMasterDirectoryBlock RECORD 0 +; These first fields are also used by MFS +drSigWord ds.w 1 ; offset: $0 (0) ; volume signature +drCrDate ds.l 1 ; offset: $2 (2) ; date and time of volume creation +drLsMod ds.l 1 ; offset: $6 (6) ; date and time of last modification +drAtrb ds.w 1 ; offset: $A (10) ; volume attributes +drNmFls ds.w 1 ; offset: $C (12) ; number of files in root folder +drVBMSt ds.w 1 ; offset: $E (14) ; first block of volume bitmap +drAllocPtr ds.w 1 ; offset: $10 (16) ; start of next allocation search +drNmAlBlks ds.w 1 ; offset: $12 (18) ; number of allocation blocks in volume +drAlBlkSiz ds.l 1 ; offset: $14 (20) ; size (in bytes) of allocation blocks +drClpSiz ds.l 1 ; offset: $18 (24) ; default clump size +drAlBlSt ds.w 1 ; offset: $1C (28) ; first allocation block in volume +drNxtCNID ds.l 1 ; offset: $1E (30) ; next unused catalog node ID +drFreeBks ds.w 1 ; offset: $22 (34) ; number of unused allocation blocks +drVN ds Str27 ; offset: $24 (36) ; volume name +; Master Directory Block extensions for HFS +drVolBkUp ds.l 1 ; offset: $40 (64) ; date and time of last backup +drVSeqNum ds.w 1 ; offset: $44 (68) ; volume backup sequence number +drWrCnt ds.l 1 ; offset: $46 (70) ; volume write count +drXTClpSiz ds.l 1 ; offset: $4A (74) ; clump size for extents overflow file +drCTClpSiz ds.l 1 ; offset: $4E (78) ; clump size for catalog file +drNmRtDirs ds.w 1 ; offset: $52 (82) ; number of directories in root folder +drFilCnt ds.l 1 ; offset: $54 (84) ; number of files in volume +drDirCnt ds.l 1 ; offset: $58 (88) ; number of directories in volume +drFndrInfo ds.l 8 ; offset: $5C (92) ; information used by the Finder +drEmbedSigWord ds.w 1 ; offset: $7C (124) ; embedded volume signature (formerly drVCSize) +drEmbedExtent ds HFSExtentDescriptor ; offset: $7E (126) ; embedded volume location and size (formerly drVBMCSize and drCtlCSize) +drXTFlSize ds.l 1 ; offset: $82 (130) ; size of extents overflow file +drXTExtRec ds HFSExtentRecord ; offset: $86 (134) ; extent record for extents overflow file +drCTFlSize ds.l 1 ; offset: $92 (146) ; size of catalog file +drCTExtRec ds HFSExtentRecord ; offset: $96 (150) ; extent record for catalog file +sizeof EQU * ; size: $A2 (162) + ENDR + + +; ---------- HFS and HFS Plus B-tree structures ---------- +; BTNodeDescriptor -- Every B-tree node starts with these fields. +BTNodeDescriptor RECORD 0 +fLink ds.l 1 ; offset: $0 (0) ; next node at this level +bLink ds.l 1 ; offset: $4 (4) ; previous node at this level +kind ds.b 1 ; offset: $8 (8) ; kind of node (leaf, index, header, map) +height ds.b 1 ; offset: $9 (9) ; zero for header, map; child is one more than parent +numRecords ds.w 1 ; offset: $A (10) ; number of records in this node +reserved ds.w 1 ; offset: $C (12) ; reserved; set to zero +sizeof EQU * ; size: $E (14) + ENDR + +; Constants for BTNodeDescriptor kind +kBTLeafNode EQU -1 +kBTIndexNode EQU 0 +kBTHeaderNode EQU 1 +kBTMapNode EQU 2 + + +; BTHeaderRec -- The first record of a B-tree header node +BTHeaderRec RECORD 0 +treeDepth ds.w 1 ; offset: $0 (0) ; maximum height (usually leaf nodes) +rootNode ds.l 1 ; offset: $2 (2) ; node number of root node +leafRecords ds.l 1 ; offset: $6 (6) ; number of leaf records in all leaf nodes +firstLeafNode ds.l 1 ; offset: $A (10) ; node number of first leaf node +lastLeafNode ds.l 1 ; offset: $E (14) ; node number of last leaf node +nodeSize ds.w 1 ; offset: $12 (18) ; size of a node, in bytes +maxKeyLength ds.w 1 ; offset: $14 (20) ; reserved +totalNodes ds.l 1 ; offset: $16 (22) ; total number of nodes in tree +freeNodes ds.l 1 ; offset: $1A (26) ; number of unused (free) nodes in tree +reserved1 ds.w 1 ; offset: $1E (30) ; unused +clumpSize ds.l 1 ; offset: $20 (32) ; reserved +btreeType ds.b 1 ; offset: $24 (36) ; reserved +reserved2 ds.b 1 ; offset: $25 (37) ; reserved +attributes ds.l 1 ; offset: $26 (38) ; persistent attributes about the tree +reserved3 ds.l 16 ; offset: $2A (42) ; reserved +sizeof EQU * ; size: $6A (106) + ENDR