large volume support (WIP, untested).

the general theory is, multiply the extents by the allocation adjustment to get physical block offsets.
currently, comparisons are still 16-bit though.
This commit is contained in:
Kelvin Sherlock 2021-07-22 23:58:20 -04:00
parent c855701ffe
commit 95aa4d8bd5
3 changed files with 287 additions and 62 deletions

View File

@ -15,7 +15,7 @@ loader : loader.omf loader.rii | hfs24.po
# bootblock.omf : bootblock.obj # bootblock.omf : bootblock.obj
# mpw linkiigs bootblock.obj -o bootblock.omf # mpw linkiigs bootblock.obj -o bootblock.omf
bootblock.obj : bootblock.aii hfs.aii bootblock.obj : bootblock.aii hfs.aii smartport.aii
# mpw asmiigs bootblock.aii -o bootblock.obj # mpw asmiigs bootblock.aii -o bootblock.obj
loader.obj : loader.aii hfs.aii macros.aii loader.obj : loader.aii hfs.aii macros.aii

View File

@ -9,30 +9,59 @@
include 'hfs.aii' include 'hfs.aii'
string asis string asis
blanks on blanks on
__smartport__ set 1 __smartport__ set 1
if __smartport__ then
include 'smartport.aii'
endif
;
; 32-bit version large volumes.
ExtendedExtent RECORD 0
startBlock ds.l 1 ; offset: $0 (0) ; first allocation block
blockCount ds.l 1 ; offset: $4 (8) ; number of allocation blocks
sizeof EQU * ; size: $8 (8)
ENDR
zp record 0 zp record 0
slot ds.w 1 slot ds.w 1
;vector ds.w 1 ;vector ds.w 1
offset ds.w 1 startingBlock ds.w 1
blockMultiplier ds.w 1
bnum ds.w 1 bnum ds.w 1
count ds.w 1 count ds.w 1
extents ds.b 3*HFSExtentDescriptor.sizeof
extents ds.b 3*ExtendedExtent.sizeof
; multiplication stuff
m1 ds.w 1
m2 ds.l 1
m3 ds.l 1
if * >= $42 then
aerror 'too much zero-page space'
endif
endr endr
if not __smartport__ then if not __smartport__ then
pro record $42 pro record $42
cmd ds.b 1 cmd ds.b 1
unit ds.b 1 unit ds.b 1
buffer ds.b 2 dataBuffer ds.b 2
block ds.b 2 blockNumber ds.b 2
endr endr
endif endif
@ -43,6 +72,7 @@ data record $2000
entry read_block, read_block_abs, read_extent_block entry read_block, read_block_abs, read_extent_block
entry vector entry vector
entry extent_to_extent
boot proc boot proc
longi off longi off
@ -56,6 +86,7 @@ boot proc
if not __smartport__ then if not __smartport__ then
stx pro.unit stx pro.unit
endif endif
txa txa
lsr a lsr a
lsr a lsr a
@ -113,13 +144,14 @@ ok
longa on longa on
stz offset ; stz startingBlock
; stz drAlBlkSiz
stz bnum stz bnum
stz count stz count
if not __smartport__ then if not __smartport__ then
lda #data lda #data
sta pro.buffer sta pro.dataBuffer
endif endif
lda #2 lda #2
jsr read_block_abs jsr read_block_abs
@ -129,6 +161,9 @@ ok
; ;
; wait a minute... max 65535 blocks, therefore high word of allocation block, etc, always 0. ; wait a minute... max 65535 blocks, therefore high word of allocation block, etc, always 0.
; i assume hfs use 32-bit links in the btree for in-memory use (24-bit or 32 pointers) ; i assume hfs use 32-bit links in the btree for in-memory use (24-bit or 32 pointers)
;
; actually, offset could be 32-bit due to large allocation blocks. however, that's unreasonably large for the
; catalog file or boot loader file.
; ;
; search for a file named ! in the root directory. ; search for a file named ! in the root directory.
@ -138,22 +173,39 @@ ok
with HFSMasterDirectoryBlock with HFSMasterDirectoryBlock
lda data+drAlBlSt lda data+drAlBlSt
xba xba
sta offset sta startingBlock
; drAlBlkSiz is actually a 32-bit number.
ldx #3*HFSExtentDescriptor.sizeof-2 ;
@cloop lda data+drCTExtRec,x ; lda data+drAlBlkSiz+2
; xba
; sta drAlBlkSiz
; xba
lda data+drAlBlkSiz+1
xba xba
sta extents,x lsr a ; / 2
dex sta blockMultiplier ; 0 = 512 byte blocks, 1 =
dex
bpl @cloop
; ldx #3*HFSExtentDescriptor.sizeof-2
;@cloop lda data+drCTExtRec,x
; xba
; sta extents,x
; dex
; dex
; bpl @cloop
ldy #drCTExtRec ; offset
jsr extent_to_extent
endwith endwith
; lda offset ; lda drAlBlSt
; clc ; clc
; adc extents ; adc extents
lda extents lda #0
jsr read_block ldx #0
jsr read_extent_block
; ;
; block should be a btree header block. find the first leaf node. ; block should be a btree header block. find the first leaf node.
@ -170,8 +222,6 @@ ok
; ;
; assert leaf < # allocated lbocks? ; assert leaf < # allocated lbocks?
; ;
;lda leaf
; s/b leaf + cat extent + offset; todo - this offset is in terms of the catalog extent
jsr read_extent_block jsr read_extent_block
lda data+BTNodeDescriptor.numRecords ; # of records lda data+BTNodeDescriptor.numRecords ; # of records
@ -237,35 +287,43 @@ found
sta count sta count
; todo -- all extents... ; todo -- all extents...
lda data+8+dataExtents,y ; lda data+8+dataExtents,y
xba ; xba
sta extents ; sta extents
lda data+8+dataExtents+2,y ; lda data+8+dataExtents+2,y
xba ; xba
sta extents+2 ; sta extents+2
tya
clc
adc #8+dataExtents
tay
jsr extent_to_extent
; now load the blocks and ; now load the blocks and
; lda #$2000 ; lda #$2000
; if __smartport__ then ; if __smartport__ then
; sta sp.buffer ; sta sp.dataBuffer
; else ; else
; sta pro.buffer ; sta pro.dataBuffer
; endif ; endif
stz bnum stz bnum
@loop @loop
lda bnum lda bnum
ldx #0
jsr read_extent_block jsr read_extent_block
inc bnum inc bnum
lda #512 lda #512
clc clc
if __smartport__ then if __smartport__ then
import sp_buffer import sp:IOBlockDCB
adc sp_buffer adc sp.dataBuffer
sta sp_buffer sta sp.dataBuffer
else else
adc pro.buffer adc pro.dataBuffer
sta pro.buffer sta pro.dataBuffer
endif endif
dec count dec count
bne @loop bne @loop
@ -284,16 +342,11 @@ found
if __smartport__ then if __smartport__ then
sp record sp record
entry sp_buffer, sp_block
ReadBlock equ $01
pcount dc.b 3
unit dc.b 1 ; hard-coded
sp_buffer
buffer dc.w $2000
sp_block
block dc.l 1 ; actually 24-bit
pCount dc.b 3
unit dc.b 1 ; hard-coded
dataBuffer dc.w $2000
blockNumber dc.l 1 ; actually 24-bit
endr endr
endif endif
@ -309,17 +362,14 @@ read_block proc
; ;
with zp with zp
clc clc
adc offset adc startingBlock
read_block_abs read_block_abs
;
; based on testing, this drops into emulation mode, so do it and recover.
;
if __smartport__ then if __smartport__ then
sta sp.block sta sp.blockNumber
else else
sta pro.block sta pro.blockNumber
endif endif
php php
@ -328,7 +378,7 @@ read_block_abs
dc.b $20 ; jsr dc.b $20 ; jsr
vector dc.w $ffff vector dc.w $ffff
if __smartport__ then if __smartport__ then
dc.b sp.ReadBlock dc.b Command.ReadBlock
dc.w sp dc.w sp
endif endif
@ -344,31 +394,119 @@ read_extent_block proc
; This doesn't check beyond the 3rd extent ; This doesn't check beyond the 3rd extent
with zp,HFSExtentDescriptor with zp,ExtendedExtent
; TODO - not yet 32-bit clean.
@0 @0
cmp extents+0+blockCount cmp extents+(sizeof*0)+blockCount
bcs @1 bcs @1
; clc ; clc
adc extents+0+startBlock adc extents+(sizeof*0)+startBlock
bra read_block bra read_block
@1 sbc extents+0+blockCount @1 sbc extents+(sizeof*0)+blockCount
cmp extents+4+blockCount cmp extents+(sizeof*1)+blockCount
bcs @2 bcs @2
; clc ; clc
adc extents+4+startBlock adc extents+(sizeof*1)+startBlock
bra read_block bra read_block
@2 sbc extents+4+blockCount @2 sbc extents+(sizeof*1)+blockCount
cmp extents+8+blockCount cmp extents+(sizeof*2)+blockCount
bcs @3 bcs @3
adc extents+8+startBlock adc extents+(sizeof*2)+startBlock
bra read_block bra read_block
@3 brk $ea @3 brk $ea
endp endp
multiply proc
; inputs: m1 (16-bit), m2 (32-bit)
; outputs: m3 (32-bit)
; m1, m2 clobbered
with zp
stz m3
stz m3+2
lda m1
beq rts
lda m2
ora m3
beq rts
loop
lsr m1
bcc next
add clc
lda m2
adc m3
sta m3
lda m2+2
adc m3+2
sta m3+2
next asl m2
rol m2+2
lda m1
bne loop
rts rts
endp
extent_to_extent proc
; y = offset into data.
; clobbers x, y
with zp
import multiply
ldx #0
loop1
lda data,y
xba
sta extents,x
stz extents+2,x
iny
iny
inx
inx
inx
inx
cpx #3*4*2
blt loop1
; now multiply...
lda blockMultiplier
dec a
beq rts
ldx #3*4*2-4
loop2
lda blockMultiplier
sta m1
lda extents+0,x
sta m2
stz m2+2
jsr multiply
lda m3
sta extents+0,x
lda m3+2
sta extents+2,x
dex
dex
dex
dex
bpl loop2
rts rts
endp
end end

87
smartport.aii Normal file
View File

@ -0,0 +1,87 @@
Command record 0
Status equ $00
ReadBlock equ $01
WriteBlock equ $02
Format equ $03
Control equ $04
Init equ $05
Open equ $06 ; character device
Close equ $07 ; character device
Read equ $08
Write equ $09
SetFormatOption equ $0a
GetFormatOption equ $0b
endr
Error record 0
badCommand equ $01
badPcount equ $04
busError equ $06
badUnit equ $11
noInterrupt equ $1f
badCode equ $21
badParameter equ $22
ioError equ $27
noDrive equ $28
noWrite equ $2b
badBlock equ $2d
diskSwitch equ $2e
offLine equ $2f
; $30-$3f = device specific
; $40-$4f = reserved
; $50-$5f = non fatal
; $60-$6f = non fatal version of $20-$2f
ioTerm equ $69
endr
StatusDCB record 0
pCount ds.b 1
unit ds.b 1
statusList ds.w 1
statusCode ds.b 1
endr
IOBlockDCB record 0
pCount ds.b 1
unit ds.b 1
dataBuffer ds.w 1
blockNumber ds.b 3 ; 24-bit
endr
FormatDCB record 0
pCount ds.b 1
unit ds.b 1
endr
ControlDCB record 0
pCount ds.b 1
unit ds.b 1
controlList ds.w 1
controlCode ds.b 1
endr
InitDCB record 0
pCount ds.b 1
unit ds.b 1
endr
OpenDCB record 0
pCount ds.b 1
unit ds.b 1
endr
CloseDCB record 0
pCount ds.b 1
unit ds.b 1
endr
IODCB record 0
pCount ds.b 1
unit ds.b 1
dataBuffer ds.w 1
byteCount ds.w 1
address ds.b 3 ; 24-bit
endr