Support for variable block size (ie, volumes > 32 MB)

Squashed commit of the following:

commit 44a6544242
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Wed Aug 11 22:10:11 2021 -0400

    improved 32-bit (well, smartport is 24-bit) block support

commit 7fc041289f
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Wed Aug 4 23:49:15 2021 -0400

    convert the extent blocks into 32-bit absolute blocks when loading.
    Currently the block comparisons are still 16-bit, though.

commit 0fabe65aca
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Tue Aug 3 20:13:27 2021 -0400

    move stack adjustment code to take effect from the callback routines

commit 6da1f9fa3c
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Tue Jul 27 21:31:23 2021 -0400

    re-arrange to avoid relative expression warning

commit dbfe66cc99
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Tue Jul 27 21:31:01 2021 -0400

    use smartport.aii

commit 95aa4d8bd5
Author: Kelvin Sherlock <ksherlock@gmail.com>
Date:   Thu Jul 22 23:58:20 2021 -0400

    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-08-15 20:45:46 -04:00
parent c855701ffe
commit e02675057f
4 changed files with 695 additions and 250 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,40 +9,68 @@
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
data record $2000 buffer equ $2000
ds.b 512
endr
entry read_block, read_block_abs, read_extent_block entry read_block_abs, read_extent_block
entry vector entry vector
entry extent_to_extent
boot proc boot proc
longi off longi off
@ -56,6 +84,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,14 +142,16 @@ 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 #buffer
sta pro.buffer sta pro.dataBuffer
endif endif
ldx #0
lda #2 lda #2
jsr read_block_abs jsr read_block_abs
@ -129,6 +160,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.
@ -136,33 +170,50 @@ ok
; ;
; ;
with HFSMasterDirectoryBlock with HFSMasterDirectoryBlock
lda data+drAlBlSt lda buffer+drAlBlSt
xba xba
sta offset sta startingBlock
; drAlBlkSiz is actually a 32-bit number.
;
; lda buffer+drAlBlkSiz+2
; xba
; sta drAlBlkSiz
; xba
lda buffer+drAlBlkSiz+1
xba
lsr a ; / 2
sta blockMultiplier ; 0 = 512 byte blocks, 1 =
; ldx #3*HFSExtentDescriptor.sizeof-2
;@cloop lda buffer+drCTExtRec,x
; xba
; sta extents,x
; dex
; dex
; bpl @cloop
ldy #drCTExtRec ; offset
jsr extent_to_extent
ldx #3*HFSExtentDescriptor.sizeof-2
@cloop lda data+drCTExtRec,x
xba
sta extents,x
dex
dex
bpl @cloop
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.
; ;
with BTHeaderRec with BTHeaderRec
; lda data+BTNodeDescriptor.sizeof+firstLeafNode ; lda buffer+BTNodeDescriptor.sizeof+firstLeafNode
; xba ; xba
; sta leaf+2 ; sta leaf+2
lda data+BTNodeDescriptor.sizeof+firstLeafNode+2 lda buffer+BTNodeDescriptor.sizeof+firstLeafNode+2
xba xba
; sta bnum ; sta bnum
@ -170,11 +221,9 @@ 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 buffer+BTNodeDescriptor.numRecords ; # of records
beq advance beq advance
xba xba
@ -183,19 +232,19 @@ ok
again again
ldx #512-2 ; last entry ldx #512-2 ; last entry
@loop @loop
lda data,x ; entry offset lda buffer,x ; entry offset
xba xba
tay tay
lda data+HFSCatalogKey.parentID,y ; parent id lda buffer+HFSCatalogKey.parentID,y ; parent id
bne notfound bne notfound
lda data+HFSCatalogKey.parentID+2,y lda buffer+HFSCatalogKey.parentID+2,y
xba xba
cmp #2 cmp #2
blt @next blt @next
beq @name beq @name
bge notfound bge notfound
@name ; name is a p-string. @name ; name is a p-string.
lda data+HFSCatalogKey.nodeName,y lda buffer+HFSCatalogKey.nodeName,y
cmp #$2101 ; pstr ! cmp #$2101 ; pstr !
beq found beq found
bge notfound bge notfound
@ -205,7 +254,7 @@ again
dec count dec count
bne @loop bne @loop
advance ; next block! advance ; next block!
lda data+BTNodeDescriptor.fLink+2 lda buffer+BTNodeDescriptor.fLink+2
beq notfound beq notfound
xba xba
jsr read_extent_block jsr read_extent_block
@ -224,12 +273,12 @@ found
; assume < 65535 bytes :) ; assume < 65535 bytes :)
with HFSCatalogFile with HFSCatalogFile
lda data+8+recordType,y lda buffer+8+recordType,y
and #$00ff and #$00ff
cmp #kHFSFileRecord cmp #kHFSFileRecord
bne notfound bne notfound
lda data+8+dataPhysicalSize+2,y lda buffer+8+dataPhysicalSize+2,y
; xba ; xba
lsr a ; >>9 since already xba lsr a ; >>9 since already xba
and #%01111111 and #%01111111
@ -237,35 +286,43 @@ found
sta count sta count
; todo -- all extents... ; todo -- all extents...
lda data+8+dataExtents,y ; lda buffer+8+dataExtents,y
xba ; xba
sta extents ; sta extents
lda data+8+dataExtents+2,y ; lda buffer+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,23 +341,18 @@ 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
read_block proc read_block_abs proc
entry read_block_abs entry read_block_abs_long
entry vector entry vector
; input ; input
@ -308,27 +360,26 @@ read_block proc
; will be adjusted for allocation block offset ; will be adjusted for allocation block offset
; ;
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
stx sp.blockNumber+2
else else
sta pro.block sta pro.blockNumber
endif endif
read_block_abs_long
php php
sec sec
xce xce
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
@ -339,36 +390,178 @@ vector dc.w $ffff
@fail brk $ea @fail brk $ea
endp endp
macro
ifcs &p1,&p2
bcc @0
&p1 &p2
@0
mend
read_extent_block proc read_extent_block proc
; a = block # ; a = block #
; This doesn't check beyond the 3rd extent ; This doesn't check beyond the 3rd extent
with zp,HFSExtentDescriptor import read_block_abs_long
with zp,ExtendedExtent
@0 @0
cmp extents+0+blockCount cmp extents+(sizeof*0)+blockCount
bcs @1 bcs @1
; clc ; clc
adc extents+0+startBlock ldx #sizeof*0+startBlock
bra read_block bra found
@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 ldx #sizeof*1+startBlock
bra read_block bra found
@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 ldx #sizeof*2+startBlock
bra read_block bra found
@3 brk $ea @3 brk $ea
found ;
clc
adc extents,x
sta sp.blockNumber
lda #0
adc extents+2,x
sta sp.blockNumber+2
clc
lda startingBlock
adc sp.blockNumber
sta sp.blockNumber
lda #0
adc sp.blockNumber+2
sta sp.blockNumber+2
bra read_block_abs_long
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 buffer.
; clobbers x, y
with zp,ExtendedExtent
import multiply
ldx #0
loop1
lda buffer,y
xba
sta extents,x
stz extents+2,x
iny
iny
inx
inx
inx
inx
cpx #sizeof*3
blt loop1
; now multiply...
lda blockMultiplier
dec a
beq offset
ldx #sizeof*3-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
offset
if 0 then
; now add the block offset to the starting block.
lda startingBlock
clc
adc extents+(ExtendedExtent.sizeof*0)+startBlock
sta extents+(ExtendedExtent.sizeof*0)+startBlock
lda #0
adc extents+(ExtendedExtent.sizeof*0)+startBlock+2
sta extents+(ExtendedExtent.sizeof*0)+startBlock+2
lda startingBlock
clc
adc extents+(ExtendedExtent.sizeof*1)+startBlock
sta extents+(ExtendedExtent.sizeof*1)+startBlock
lda #0
adc extents+(ExtendedExtent.sizeof*1)+startBlock+2
sta extents+(ExtendedExtent.sizeof*1)+startBlock+2
lda startingBlock
clc
adc extents+(ExtendedExtent.sizeof*2)+startBlock
sta extents+(ExtendedExtent.sizeof*2)+startBlock
lda #0
adc extents+(ExtendedExtent.sizeof*2)+startBlock+2
sta extents+(ExtendedExtent.sizeof*2)+startBlock+2
endif
rts
endp endp
end end

View File

@ -18,9 +18,24 @@
__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
buffer equ $3000 buffer equ $3000
dp record 0 zp record 0
ptr ds.l 1 ptr ds.l 1
path ds.l 1 path ds.l 1
@ -38,25 +53,42 @@ at ds.w 1
st ds.w 1 st ds.w 1
file_id ds.l 1 file_id ds.l 1
extents ds.b 3*ExtendedExtent.sizeof
; multiplication stuff
m1 ds.w 1
m2 ds.l 1
m3 ds.l 1
; too much zp space...
if not __smartport__ and * >= $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
entry read_block, read_block_abs entry read_block_abs, read_block_abs_long
entry prepare_path, cat_lookup entry prepare_path, cat_lookup
entry read_cat_block, read_file_block entry read_cat_block, read_file_block
entry extent_to_extent
header proc header proc
@ -82,10 +114,12 @@ data record
;unit dc.w 0 ;unit dc.w 0
;vector dc.w 0 ;vector dc.w 0
block_offset dc.w 0 startingBlock dc.w 0
blockMultiplier dc.w 0
cat_extents dcb.w 6, 0
file_extents dcb.w 6, 0 cat_extents ds.b 3*ExtendedExtent.sizeof
file_extents ds.b 3*ExtendedExtent.sizeof
cat_root dc.w 0 cat_root dc.w 0
@ -106,21 +140,22 @@ cat_str dcb.b 32, 0
endr endr
if __smartport__ then if __smartport__ then
sp record sp record
ReadBlock equ $01 pCount dc.b 3
pcount dc.b 3 unit dc.b 1
unit dc.b 1 dataBuffer dc.w $3000 ; name conflict...
buffer dc.w $3000 ; name conflict... blockNumber dc.l 0 ; actually 24-bit
block dc.l 0 ; actually 24-bit endr
endr
endif endif
_stack ds.w 1
getbootname proc getbootname proc
; getbootname(GSString *) ; getbootname(GSString *)
; return string needs a leading colon. ; return string needs a leading colon.
with dp with zp
plx ; rts plx ; rts
ply ply
@ -133,13 +168,26 @@ getbootname proc
phk phk
plb plb
; prepare the stack for emulation mode
tsx
stx _stack
ldx #$01ff ; should be enough space
txs
; get the volume name from the HFS MDB.... ; get the volume name from the HFS MDB....
if not __smartport__ then if not __smartport__ then
lda #buffer lda #buffer
sta pro.buffer sta pro.dataBuffer
endif endif
lda #2 lda #2
ldx #0
jsr read_block_abs jsr read_block_abs
; restore the stack. does not affect a/carry
ldx _stack
txs
bcs exit bcs exit
with HFSMasterDirectoryBlock with HFSMasterDirectoryBlock
@ -176,7 +224,7 @@ exit
getfstname proc getfstname proc
; getfstname(GSString *) ; getfstname(GSString *)
with dp with zp
plx ; rts plx ; rts
ply ply
@ -211,7 +259,7 @@ name str.w 'hfs.fst'
readfile proc readfile proc
; (eof, aux type, file type) readfile(GSString *, void *) ; (eof, aux type, file type) readfile(GSString *, void *)
with dp with zp
plx ; rts plx ; rts
ply ply
@ -228,6 +276,12 @@ readfile proc
phk phk
plb plb
; prepare the stack for emulation mode
tsx
stx _stack
ldx #$01ff ; should be enough space
txs
jsr prepare_path jsr prepare_path
bcs exit bcs exit
@ -235,6 +289,9 @@ readfile proc
jsr cat_lookup jsr cat_lookup
bcs exit bcs exit
; now read file, one block at a time, ; now read file, one block at a time,
; and copy to ptr. ; and copy to ptr.
lda blocks lda blocks
@ -243,7 +300,7 @@ readfile proc
if not __smartport__ then if not __smartport__ then
lda #buffer lda #buffer
sta pro.buffer sta pro.dataBuffer
endif endif
; need to re-set cmd/slot as well? ; need to re-set cmd/slot as well?
@ -280,6 +337,9 @@ rdone
; ... ; ...
ldx _stack
txs
; stack: b, rts, ; stack: b, rts,
lda ft lda ft
sta 4,s sta 4,s
@ -292,7 +352,12 @@ rdone
lda #0 lda #0
clc clc
plb
rts
exit exit
ldx _stack
txs
plb plb
rts rts
@ -300,7 +365,7 @@ exit
prepare_path proc prepare_path proc
with dp, data with zp, data
; optimism ; optimism
stz r0 ; offset into path stz r0 ; offset into path
@ -445,135 +510,153 @@ s3 dc.b 'xxSYSTEM:FSTS:'
endp endp
read_block proc
entry read_block_abs
entry vector
; input
; a = hfs block #
; will be adjusted for allocation block offset
;
with dp
clc
adc data.block_offset
read_block_abs
; todo -- need to save/restore dp and stack
if __smartport__ then
sta sp.block
else
sta pro.block
endif
;
; need to save/restore the stack. start.gs.os will call w/ high stack
;
tsc
sta _stack
lda #$01bf ; should be enough space
tcs
clc
php
sec
xce
dc.b $20 ; jsr
vector dc.w $ffff
if __smartport__ then
dc.b sp.ReadBlock
dc.w sp
endif
bcs @fail
xce
plp
lda _stack
tcs
lda #0
rts
@fail
clc
xce
plp
tax ; save
lda _stack
tcs
sec
txa
and #$ff
rts
_stack ds.w 1
endp
read_file_block proc read_file_block proc
; a = block # ; a = block #
with data,HFSExtentDescriptor with data,ExtendedExtent
@0 @0
cmp file_extents+0+blockCount cmp file_extents+(sizeof*0)+blockCount
bcs @1 bcs @1
; clc ; clc
adc file_extents+0+startBlock ldx #sizeof*0+startBlock
bra read_block bra found
@1 sbc file_extents+0+blockCount @1 sbc file_extents+(sizeof*0)+blockCount
cmp file_extents+4+blockCount cmp file_extents+(sizeof*1)+blockCount
bcs @2 bcs @2
; clc ; clc
adc file_extents+4+startBlock ldx #sizeof*1+startBlock
bra read_block bra found
@2 sbc file_extents+4+blockCount @2 sbc file_extents+(sizeof*1)+blockCount
cmp file_extents+8+blockCount cmp file_extents+(sizeof*2)+blockCount
bcs @3 bcs @3
adc file_extents+8+startBlock ldx #sizeof*2+startBlock
bra read_block bra found
@3 @3
lda #outOfRange ; too big lda #outOfRange ; too big
sec sec
rts rts
found ;
clc
adc file_extents,x
sta sp.blockNumber
lda #0
adc file_extents+2,x
sta sp.blockNumber+2
clc
lda startingBlock
adc sp.blockNumber
sta sp.blockNumber
lda #0
adc sp.blockNumber+2
sta sp.blockNumber+2
bra read_block_abs_long
endp endp
read_cat_block proc read_cat_block proc
; a = block # ; a = block #
with data,HFSExtentDescriptor
with data,ExtendedExtent
@0 @0
cmp cat_extents+0+blockCount cmp cat_extents+(sizeof*0)+blockCount
bcs @1 bcs @1
; clc ; clc
adc cat_extents+0+startBlock ldx #sizeof*0+startBlock
bra read_block bra found
@1 sbc cat_extents+0+blockCount @1 sbc cat_extents+(sizeof*0)+blockCount
cmp cat_extents+4+blockCount cmp cat_extents+(sizeof*1)+blockCount
bcs @2 bcs @2
; clc ; clc
adc cat_extents+4+startBlock ldx #sizeof*1+startBlock
bra read_block bra found
@2 sbc cat_extents+4+blockCount @2 sbc cat_extents+(sizeof*1)+blockCount
cmp cat_extents+8+blockCount cmp cat_extents+(sizeof*2)+blockCount
bcs @3 bcs @3
adc cat_extents+8+startBlock ldx #sizeof*2+startBlock
bra read_block bra found
@3 @3
lda #outOfRange ; too big lda #outOfRange ; too big
sec sec
rts rts
found ;
clc
adc cat_extents,x
sta sp.blockNumber
lda #0
adc cat_extents+2,x
sta sp.blockNumber+2
clc
lda startingBlock
adc sp.blockNumber
sta sp.blockNumber
lda #0
adc sp.blockNumber+2
sta sp.blockNumber+2
bra read_block_abs_long
endp
read_block_abs proc
entry read_block_abs_long
entry vector
; input
; a = hfs block #
; will be adjusted for allocation block offset
;
; clc
; adc data.startingBlock
if __smartport__ then
sta sp.blockNumber
stx sp.blockNumber+2
else
sta pro.blockNumber
endif
read_block_abs_long
php
sec
xce
dc.b $20 ; jsr
vector dc.w $ffff
if __smartport__ then
dc.b Command.ReadBlock
dc.w sp
endif
bcs @fail
xce
plp
lda #0
clc
rts
@fail
clc
xce
plp
and #$ff
sec
rts
endp endp
@ -585,9 +668,9 @@ cat_lookup proc
with data with data
bnum equ dp.r0 bnum equ zp.r0
prev equ dp.r1 prev equ zp.r1
count equ dp.r2 count equ zp.r2
; search for a file and a parent directory. ; search for a file and a parent directory.
@ -795,7 +878,7 @@ match proc
; a match! ; a match!
; store the file type, aux type, eof, and extent pointers. ; store the file type, aux type, eof, and extent pointers.
with dp, data with zp, data
lda buffer+HFSCatalogKey.keyLength,y lda buffer+HFSCatalogKey.keyLength,y
; and #$ff ; and #$ff
@ -830,7 +913,7 @@ folder
sta ft sta ft
lda #$0d lda #$0d
sta st ; storage type sta st ; storage type
ldx #12-2 ldx #3*ExtendedExtent.sizeof-2
@eloop @eloop
stz file_extents,x stz file_extents,x
dex dex
@ -871,30 +954,19 @@ file
lda #1 lda #1
sta st ; storage type sta st ; storage type
phy ; save
lda buffer+dataExtents+0,y tya
xba clc
sta file_extents+0 adc #dataExtents
tay
lda buffer+dataExtents+2,y ; ldy #dataExtents
xba jsr extent_to_extent
sta file_extents+2 lda #3*ExtendedExtent.sizeof-1
ldx #extents
lda buffer+dataExtents+4,y ldy #file_extents
xba mvn $00,$00
sta file_extents+4 ; a, x, y clobbered.
ply
lda buffer+dataExtents+6,y
xba
sta file_extents+6
lda buffer+dataExtents+8,y
xba
sta file_extents+8
lda buffer+dataExtents+10,y
xba
sta file_extents+10
lda buffer+fileID+2,y lda buffer+fileID+2,y
xba xba
@ -906,7 +978,7 @@ file
; file type aux type logic. ; file type aux type logic.
; only support pdos encoding, nothing fancy. ; only support pdos encoding, nothing fancy.
; 'p' filetype aux type pdos ; 'p' filetype aux type pdos
; where filetype = 80bit, aux type = 16 bit big endian ; where filetype = 8 bit, aux type = 16 bit big endian
stz ft stz ft
stz at stz at
@ -964,7 +1036,7 @@ startup proc
; read :system:start.gsos, load into memory @ $6800 ; read :system:start.gsos, load into memory @ $6800
; aux type is stored in auxtype ; aux type is stored in auxtype
with dp, data with zp, data
; assume 16-bit, etc. ; assume 16-bit, etc.
@ -982,7 +1054,7 @@ startup proc
if not __smartport__ then if not __smartport__ then
lda #buffer lda #buffer
sta pro.buffer sta pro.dataBuffer
short m short m
lda #1 lda #1
sta pro.cmd sta pro.cmd
@ -991,27 +1063,35 @@ startup proc
with HFSMasterDirectoryBlock with HFSMasterDirectoryBlock
lda #2 lda #2
ldx #0
jsr read_block_abs jsr read_block_abs
; can't really fail... ; shouldn't fail.
lda buffer+drAlBlSt lda buffer+drAlBlSt
xba xba
sta block_offset sta startingBlock
ldx #3*HFSExtentDescriptor.sizeof-2 lda buffer+drAlBlkSiz+1
@cloop lda buffer+drCTExtRec,x
xba xba
sta cat_extents,x lsr a ; / 2
dex sta blockMultiplier
dex
bpl @cloop ; catalog extents
ldy #drCTExtRec ; offset
jsr extent_to_extent
lda #3*ExtendedExtent.sizeof-1
ldx #extents
ldy #cat_extents
mvn $00,$00
; a, x, y clobbered.
; save the volume name while we're at it? ; save the volume name while we're at it?
endwith endwith
; find the root node. ; find the root node.
lda cat_extents lda #0
jsr read_block jsr read_cat_block
with BTHeaderRec with BTHeaderRec
lda buffer+BTNodeDescriptor.sizeof+rootNode+2 lda buffer+BTNodeDescriptor.sizeof+rootNode+2
@ -1113,9 +1193,9 @@ read
lda #$6800 lda #$6800
if __smartport__ then if __smartport__ then
sta sp.buffer sta sp.dataBuffer
else else
sta pro.buffer sta pro.dataBuffer
endif endif
@loop lda r0 @loop lda r0
@ -1124,11 +1204,11 @@ read
; clc ; clc
lda #512 lda #512
if __smartport__ then if __smartport__ then
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
inc r0 inc r0
dec blocks dec blocks
@ -1140,9 +1220,9 @@ read
lda #buffer lda #buffer
if __smartport__ then if __smartport__ then
sta sp.buffer sta sp.dataBuffer
else else
sta pro.buffer ; kind of important... sta pro.dataBuffer ; kind of important...
endif endif
lda #0 lda #0
@ -1167,4 +1247,89 @@ gsos str.w 'START.GS.OS'
dcb.b 1,0 dcb.b 1,0
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 buffer.
; clobbers x, y
with zp, data
import multiply
ldx #0
loop1
lda buffer,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