mirror of
https://github.com/ksherlock/hfs-boot.git
synced 2024-11-15 09:05:13 +00:00
e02675057f
Squashed commit of the following: commit44a6544242
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 commit7fc041289f
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. commit0fabe65aca
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 commit6da1f9fa3c
Author: Kelvin Sherlock <ksherlock@gmail.com> Date: Tue Jul 27 21:31:23 2021 -0400 re-arrange to avoid relative expression warning commitdbfe66cc99
Author: Kelvin Sherlock <ksherlock@gmail.com> Date: Tue Jul 27 21:31:01 2021 -0400 use smartport.aii commit95aa4d8bd5
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.
1336 lines
16 KiB
Plaintext
1336 lines
16 KiB
Plaintext
;
|
|
;
|
|
; loader
|
|
;
|
|
; currently limited to 512-byte blocks (32MB max filesystem)
|
|
; need to use smartport protocol to use > 65535 blocks anyhow.
|
|
;
|
|
|
|
|
|
|
|
include 'hfs.aii'
|
|
include 'macros.aii'
|
|
include 'e16.gsos'
|
|
|
|
string asis
|
|
blanks on
|
|
|
|
|
|
__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
|
|
|
|
zp record 0
|
|
ptr ds.l 1
|
|
path ds.l 1
|
|
|
|
|
|
r0 ds.w 1
|
|
r1 ds.w 1
|
|
r2 ds.w 1
|
|
r3 ds.w 1
|
|
|
|
; readfile
|
|
eof ds.l 1
|
|
blocks ds.w 1 ; shouldn't exceed $ffff blocks
|
|
ft ds.w 1
|
|
at ds.w 1
|
|
st ds.w 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
|
|
|
|
|
|
|
|
|
|
if not __smartport__ then
|
|
pro record $42
|
|
cmd ds.b 1
|
|
unit ds.b 1
|
|
dataBuffer ds.b 2
|
|
blockNumber ds.b 2
|
|
endr
|
|
|
|
endif
|
|
|
|
|
|
entry read_block_abs, read_block_abs_long
|
|
entry prepare_path, cat_lookup
|
|
entry read_cat_block, read_file_block
|
|
entry extent_to_extent
|
|
|
|
|
|
header proc
|
|
|
|
import readfile, getbootname, getfstname, startup
|
|
entry auxtype
|
|
|
|
jmp startup
|
|
nop
|
|
|
|
dc.w readfile
|
|
dc.w getbootname
|
|
dc.w getfstname
|
|
dc.w startup-header ; size of permanent code
|
|
auxtype dc.w 0
|
|
|
|
endp
|
|
|
|
|
|
data record
|
|
; store catalog info
|
|
;slot dc.w 0
|
|
;unit dc.w 0
|
|
;vector dc.w 0
|
|
|
|
startingBlock dc.w 0
|
|
blockMultiplier dc.w 0
|
|
|
|
|
|
cat_extents ds.b 3*ExtendedExtent.sizeof
|
|
file_extents ds.b 3*ExtendedExtent.sizeof
|
|
|
|
cat_root dc.w 0
|
|
|
|
system_id dc.l 0
|
|
fsts_id dc.l 0
|
|
drivers_id dc.l 0
|
|
|
|
|
|
; ctree lookup
|
|
target_parent dc.l 0
|
|
|
|
target_str_len dc.w 0
|
|
target_str dcb.b 32, 0
|
|
|
|
cat_str_len dc.w 0
|
|
cat_str dcb.b 32, 0
|
|
|
|
endr
|
|
|
|
if __smartport__ then
|
|
sp record
|
|
pCount dc.b 3
|
|
unit dc.b 1
|
|
dataBuffer dc.w $3000 ; name conflict...
|
|
blockNumber dc.l 0 ; actually 24-bit
|
|
endr
|
|
endif
|
|
|
|
|
|
_stack ds.w 1
|
|
|
|
getbootname proc
|
|
; getbootname(GSString *)
|
|
; return string needs a leading colon.
|
|
|
|
with zp
|
|
|
|
plx ; rts
|
|
ply
|
|
sty ptr
|
|
ply
|
|
sty ptr+2
|
|
phx
|
|
|
|
phb
|
|
phk
|
|
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....
|
|
if not __smartport__ then
|
|
lda #buffer
|
|
sta pro.dataBuffer
|
|
endif
|
|
lda #2
|
|
ldx #0
|
|
jsr read_block_abs
|
|
|
|
; restore the stack. does not affect a/carry
|
|
ldx _stack
|
|
txs
|
|
|
|
bcs exit
|
|
|
|
with HFSMasterDirectoryBlock
|
|
lda buffer+drVN
|
|
and #$ff
|
|
inc a ; + 1 for :
|
|
sta [ptr]
|
|
inc a ; round up and divide
|
|
lsr a
|
|
tax ; count
|
|
dex
|
|
|
|
ldy #2
|
|
lda #':'
|
|
sta [ptr],y
|
|
iny
|
|
@loop lda buffer+drVN-2,y
|
|
sta [ptr],y
|
|
iny
|
|
iny
|
|
dex
|
|
bpl @loop
|
|
|
|
clc
|
|
lda #0
|
|
|
|
exit
|
|
plb
|
|
rts
|
|
|
|
endp
|
|
|
|
|
|
getfstname proc
|
|
; getfstname(GSString *)
|
|
|
|
with zp
|
|
|
|
plx ; rts
|
|
ply
|
|
sty ptr
|
|
ply
|
|
sty ptr+2
|
|
phx
|
|
|
|
phb
|
|
phk
|
|
plb
|
|
|
|
ldy #10-2 ; 7 + 2 + 1 byte to round up.
|
|
|
|
@loop lda name,y
|
|
sta [ptr],y
|
|
dey
|
|
dey
|
|
bpl @loop
|
|
|
|
plb
|
|
clc
|
|
lda #0
|
|
rts
|
|
|
|
name str.w 'hfs.fst'
|
|
dcb.b 1,0
|
|
|
|
endp
|
|
|
|
|
|
|
|
readfile proc
|
|
; (eof, aux type, file type) readfile(GSString *, void *)
|
|
with zp
|
|
|
|
plx ; rts
|
|
ply
|
|
sty ptr ; data buffer
|
|
ply
|
|
sty ptr+2
|
|
ply
|
|
sty path ; pathname
|
|
ply
|
|
sty path+2
|
|
phx
|
|
|
|
phb
|
|
phk
|
|
plb
|
|
|
|
; prepare the stack for emulation mode
|
|
tsx
|
|
stx _stack
|
|
ldx #$01ff ; should be enough space
|
|
txs
|
|
|
|
|
|
jsr prepare_path
|
|
bcs exit
|
|
|
|
jsr cat_lookup
|
|
bcs exit
|
|
|
|
|
|
|
|
|
|
; now read file, one block at a time,
|
|
; and copy to ptr.
|
|
lda blocks
|
|
beq rdone
|
|
stz r0 ; block
|
|
|
|
if not __smartport__ then
|
|
lda #buffer
|
|
sta pro.dataBuffer
|
|
endif
|
|
; need to re-set cmd/slot as well?
|
|
|
|
@rloop
|
|
lda r0
|
|
jsr read_file_block
|
|
bcs exit
|
|
|
|
|
|
; copy to destination
|
|
pea buffer>>16 ; src
|
|
pea buffer
|
|
pei ptr+2 ; dest
|
|
pei ptr
|
|
pea 0 ; count
|
|
pea 512
|
|
_BlockMove
|
|
|
|
|
|
lda ptr
|
|
clc
|
|
adc #512
|
|
sta ptr
|
|
lda ptr+2
|
|
adc #0
|
|
sta ptr+2
|
|
|
|
inc r0
|
|
dec blocks
|
|
bne @rloop
|
|
|
|
rdone
|
|
|
|
|
|
; ...
|
|
|
|
ldx _stack
|
|
txs
|
|
|
|
; stack: b, rts,
|
|
lda ft
|
|
sta 4,s
|
|
lda at
|
|
sta 6,s
|
|
lda eof
|
|
sta 8,s
|
|
lda eof+2
|
|
sta 10,s
|
|
|
|
lda #0
|
|
clc
|
|
plb
|
|
rts
|
|
|
|
exit
|
|
ldx _stack
|
|
txs
|
|
plb
|
|
rts
|
|
|
|
endp
|
|
|
|
prepare_path proc
|
|
|
|
with zp, data
|
|
|
|
; optimism
|
|
stz r0 ; offset into path
|
|
lda system_id
|
|
sta target_parent
|
|
lda system_id+2
|
|
sta target_parent+2
|
|
|
|
|
|
lda [path]
|
|
cmp #8
|
|
blt err
|
|
|
|
; SYSTEM ?
|
|
ldx #3
|
|
ldy #2
|
|
@loop
|
|
lda [path],y
|
|
cmp s1,y
|
|
bne err
|
|
iny
|
|
iny
|
|
dex
|
|
bne @loop
|
|
|
|
lda [path],y
|
|
iny
|
|
sty r0
|
|
|
|
cmp #'D:'
|
|
beq d
|
|
cmp #'F:'
|
|
beq f
|
|
|
|
and #$ff
|
|
cmp #':'
|
|
beq sys
|
|
err lda #fileNotFound
|
|
sec
|
|
rts
|
|
|
|
sys brl target
|
|
; check for more ':' ?
|
|
|
|
d ; check for a driver folder.
|
|
lda [path]
|
|
cmp #16
|
|
blt sys
|
|
ldx #4
|
|
@loop lda [path],y
|
|
cmp s2,y
|
|
bne sys
|
|
iny
|
|
iny
|
|
dex
|
|
bne @loop
|
|
; match!
|
|
sty r0
|
|
lda drivers_id
|
|
sta target_parent
|
|
lda drivers_id+2
|
|
sta target_parent+2
|
|
brl target
|
|
|
|
f ; check for FSTs folder
|
|
lda [path]
|
|
cmp #13
|
|
blt sys
|
|
ldx #2
|
|
@loop lda [path],y
|
|
cmp s3,y
|
|
bne sys
|
|
iny
|
|
iny
|
|
dex
|
|
bne @loop
|
|
lda [path],y
|
|
and #$ff
|
|
cmp #':'
|
|
bne sys
|
|
iny
|
|
sty r0
|
|
lda fsts_id
|
|
sta target_parent
|
|
lda fsts_id+2
|
|
sta target_parent+2
|
|
|
|
; drop through
|
|
|
|
target
|
|
; now set target_str / len
|
|
lda [path]
|
|
inc a
|
|
inc a ; compensate for string length.
|
|
sec
|
|
sbc r0
|
|
beq fnf ; close enough
|
|
bmi fnf
|
|
sta target_str_len
|
|
cmp #16
|
|
bcs fnf
|
|
|
|
ldx #30
|
|
@zloop stz target_str,x
|
|
dex
|
|
dex
|
|
bpl @zloop
|
|
|
|
short m
|
|
ldx #0
|
|
@loop
|
|
lda [path],y
|
|
cmp #':'
|
|
beq fnf
|
|
cmp #'z'+1
|
|
bge @next
|
|
cmp #'a'
|
|
blt @next
|
|
and #$ff xor $20
|
|
|
|
@next sta target_str,x
|
|
iny
|
|
inx
|
|
cpx target_str_len
|
|
blt @loop
|
|
|
|
long m
|
|
lda #0
|
|
clc
|
|
rts
|
|
|
|
fnf long m
|
|
lda #fileNotFound
|
|
sec
|
|
rts
|
|
|
|
|
|
s1 dc.b 'xxSYSTEM:'
|
|
s2 dc.b 'xxSYSTEM:DRIVERS:'
|
|
s3 dc.b 'xxSYSTEM:FSTS:'
|
|
|
|
endp
|
|
|
|
|
|
read_file_block proc
|
|
; a = block #
|
|
|
|
with data,ExtendedExtent
|
|
|
|
@0
|
|
cmp file_extents+(sizeof*0)+blockCount
|
|
bcs @1
|
|
; clc
|
|
ldx #sizeof*0+startBlock
|
|
bra found
|
|
|
|
@1 sbc file_extents+(sizeof*0)+blockCount
|
|
cmp file_extents+(sizeof*1)+blockCount
|
|
bcs @2
|
|
; clc
|
|
ldx #sizeof*1+startBlock
|
|
bra found
|
|
|
|
@2 sbc file_extents+(sizeof*1)+blockCount
|
|
cmp file_extents+(sizeof*2)+blockCount
|
|
bcs @3
|
|
ldx #sizeof*2+startBlock
|
|
bra found
|
|
|
|
@3
|
|
lda #outOfRange ; too big
|
|
sec
|
|
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
|
|
|
|
read_cat_block proc
|
|
; a = block #
|
|
|
|
|
|
with data,ExtendedExtent
|
|
|
|
@0
|
|
cmp cat_extents+(sizeof*0)+blockCount
|
|
bcs @1
|
|
; clc
|
|
ldx #sizeof*0+startBlock
|
|
bra found
|
|
|
|
@1 sbc cat_extents+(sizeof*0)+blockCount
|
|
cmp cat_extents+(sizeof*1)+blockCount
|
|
bcs @2
|
|
; clc
|
|
ldx #sizeof*1+startBlock
|
|
bra found
|
|
|
|
@2 sbc cat_extents+(sizeof*1)+blockCount
|
|
cmp cat_extents+(sizeof*2)+blockCount
|
|
bcs @3
|
|
ldx #sizeof*2+startBlock
|
|
bra found
|
|
|
|
@3
|
|
lda #outOfRange ; too big
|
|
sec
|
|
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
|
|
|
|
|
|
|
|
|
|
cat_lookup proc
|
|
|
|
import name_check, match
|
|
|
|
with data
|
|
|
|
bnum equ zp.r0
|
|
prev equ zp.r1
|
|
count equ zp.r2
|
|
|
|
; search for a file and a parent directory.
|
|
|
|
lda cat_root
|
|
sta bnum
|
|
|
|
|
|
descend
|
|
ldx #-1
|
|
stx prev
|
|
|
|
next_index
|
|
lda bnum
|
|
jsr read_cat_block
|
|
bcc @ok
|
|
rts ; uhoh
|
|
@ok
|
|
lda buffer+BTNodeDescriptor.numRecords
|
|
beq advance
|
|
xba
|
|
sta count
|
|
|
|
ldx #512-2 ; last entry
|
|
eloop
|
|
lda buffer,x ; entry offset
|
|
xba
|
|
tay
|
|
lda buffer+HFSCatalogKey.parentID,y
|
|
xba
|
|
cmp target_parent+2
|
|
beq @p2
|
|
blt @lt
|
|
bge @gt
|
|
|
|
@p2 lda buffer+HFSCatalogKey.parentID+2,y
|
|
xba
|
|
cmp target_parent
|
|
beq @nm
|
|
blt @lt
|
|
bge @gt
|
|
|
|
@gt
|
|
; if this is an index node,
|
|
; we overshot, so follow the tree via prev
|
|
; to the next level.
|
|
lda prev
|
|
sta bnum
|
|
; index map is 0xff so ora / bmi works.
|
|
ora buffer+BTNodeDescriptor.kind-1
|
|
bmi fnf ; index map
|
|
bra descend
|
|
|
|
; now do a name check....
|
|
; target_name is UPPER CASE
|
|
@nm
|
|
jsr name_check
|
|
cmp #0
|
|
beq @found
|
|
bmi @lt
|
|
bra @gt
|
|
|
|
|
|
@found
|
|
; a match! if this is an index node,
|
|
; descend....
|
|
lda buffer+BTNodeDescriptor.kind-1
|
|
bmi @leaf
|
|
lda buffer+38+2,y
|
|
xba
|
|
sta bnum
|
|
bra descend
|
|
@leaf jmp match
|
|
|
|
|
|
|
|
|
|
; if this is an index node, keep it for later
|
|
@lt lda buffer+38+2,y
|
|
xba
|
|
sta prev
|
|
|
|
@next
|
|
dex
|
|
dex
|
|
dec count
|
|
bne eloop
|
|
|
|
advance
|
|
; wait a minute ... do we ever need to follow the next link?
|
|
; first entry of next node is always > target.
|
|
; so we can just descend via prev ptr.
|
|
; lda buffer+BTNodeDescriptor.fLink+2
|
|
; beq @last
|
|
; xba
|
|
; sta bnum
|
|
; bra next_index
|
|
@last ; if there was a prev node, descend into it
|
|
; but not if this is a map node
|
|
lda prev
|
|
sta bnum
|
|
ora buffer+BTNodeDescriptor.kind-1
|
|
bpl descend
|
|
; bmi fnf
|
|
; sta bnum
|
|
; bra descend
|
|
|
|
fnf
|
|
lda #fileNotFound
|
|
sec
|
|
rts
|
|
endp
|
|
|
|
name_check proc
|
|
; copy into catstr and upper case it.
|
|
|
|
; save x and y.
|
|
;
|
|
; a = 0 if match
|
|
; a = -1 if catalog entry < target
|
|
; a = +1 if catalog entry > target
|
|
|
|
with data
|
|
|
|
phx
|
|
phy ; save
|
|
|
|
|
|
;
|
|
; we need to handle 0-length strings (folder threads)
|
|
;
|
|
|
|
|
|
ldx #30
|
|
@zloop stz cat_str,x
|
|
dex
|
|
dex
|
|
bpl @zloop
|
|
stz cat_str_len
|
|
ldx #0
|
|
short m
|
|
|
|
lda buffer+HFSCatalogKey.nodeName,y
|
|
sta cat_str_len
|
|
beq cmp
|
|
|
|
; copy and upper case the string.
|
|
copy
|
|
lda buffer+HFSCatalogKey.nodeName+1,y
|
|
cmp #'a'
|
|
blt @store
|
|
cmp #'z'+1
|
|
bge @store
|
|
and #$ff xor $20
|
|
|
|
@store
|
|
sta cat_str,x
|
|
iny
|
|
inx
|
|
cpx cat_str_len
|
|
blt copy
|
|
|
|
|
|
cmp
|
|
lda target_str_len
|
|
ora cat_str_len
|
|
beq eq ; folder thread - no name.
|
|
|
|
ldx target_str_len
|
|
cpx cat_str_len
|
|
bge @x
|
|
ldx cat_str_len
|
|
@x
|
|
ldy #0
|
|
@loop
|
|
lda cat_str,y
|
|
cmp target_str,y
|
|
beq @next
|
|
blt lt
|
|
bge gt
|
|
|
|
@next
|
|
iny
|
|
dex
|
|
bne @loop
|
|
|
|
eq long m
|
|
lda #0
|
|
bra exit
|
|
|
|
lt long m
|
|
lda #-1
|
|
bra exit
|
|
|
|
gt long m
|
|
lda #1
|
|
|
|
exit
|
|
ply
|
|
plx
|
|
rts
|
|
|
|
endp
|
|
|
|
match proc
|
|
; a match!
|
|
; store the file type, aux type, eof, and extent pointers.
|
|
|
|
with zp, data
|
|
|
|
lda buffer+HFSCatalogKey.keyLength,y
|
|
; and #$ff
|
|
inc a ; length doesn't include itself
|
|
inc a ; pad to a word boundary.
|
|
and #$fe
|
|
sta r0
|
|
|
|
lda buffer,x ; x still valid
|
|
xba
|
|
clc
|
|
adc r0
|
|
tay
|
|
|
|
lda buffer+HFSCatalogFile.recordType,y
|
|
and #$ff
|
|
cmp #kHFSFolderRecord
|
|
beq folder
|
|
cmp #kHFSFileRecord
|
|
beq file
|
|
; folder thread, file thread.... invalid for us.
|
|
lda #fileNotFound
|
|
sec
|
|
rts
|
|
folder
|
|
with HFSCatalogFolder
|
|
stz eof
|
|
stz eof+2
|
|
stz blocks
|
|
stz at
|
|
lda #$f
|
|
sta ft
|
|
lda #$0d
|
|
sta st ; storage type
|
|
ldx #3*ExtendedExtent.sizeof-2
|
|
@eloop
|
|
stz file_extents,x
|
|
dex
|
|
dex
|
|
bpl @eloop
|
|
|
|
|
|
lda buffer+folderID+2,y
|
|
xba
|
|
sta file_id
|
|
lda buffer+folderID,y
|
|
xba
|
|
sta file_id+2
|
|
|
|
lda #0
|
|
clc
|
|
rts
|
|
endwith
|
|
|
|
file
|
|
with HFSCatalogFile
|
|
lda buffer+dataLogicalSize+2,y
|
|
xba
|
|
sta eof
|
|
lda buffer+dataLogicalSize,y
|
|
xba
|
|
sta eof+2
|
|
|
|
; blocks
|
|
; update if variable block size?
|
|
lda buffer+dataPhysicalSize+2,y
|
|
; xba
|
|
lsr a ; >>9 since already xba
|
|
and #%01111111
|
|
sta blocks
|
|
|
|
|
|
lda #1
|
|
sta st ; storage type
|
|
|
|
phy ; save
|
|
tya
|
|
clc
|
|
adc #dataExtents
|
|
tay
|
|
; ldy #dataExtents
|
|
jsr extent_to_extent
|
|
lda #3*ExtendedExtent.sizeof-1
|
|
ldx #extents
|
|
ldy #file_extents
|
|
mvn $00,$00
|
|
; a, x, y clobbered.
|
|
ply
|
|
|
|
lda buffer+fileID+2,y
|
|
xba
|
|
sta file_id
|
|
lda buffer+fileID,y
|
|
xba
|
|
sta file_id+2
|
|
|
|
; file type aux type logic.
|
|
; only support pdos encoding, nothing fancy.
|
|
; 'p' filetype aux type pdos
|
|
; where filetype = 8 bit, aux type = 16 bit big endian
|
|
|
|
stz ft
|
|
stz at
|
|
lda buffer+userInfo+4,y
|
|
cmp #'dp'
|
|
bne noft
|
|
lda buffer+userInfo+4+2,y
|
|
cmp #'so'
|
|
bne noft
|
|
pdos
|
|
lda buffer+userInfo,y
|
|
tax
|
|
and #$ff
|
|
cmp #'p'
|
|
bne noft
|
|
txa
|
|
xba
|
|
and #$ff
|
|
sta ft
|
|
lda buffer+userInfo+2,y
|
|
xba
|
|
sta at
|
|
noft
|
|
|
|
lda #0
|
|
clc
|
|
rts
|
|
endwith
|
|
|
|
endp
|
|
|
|
|
|
macro
|
|
&lab ifc_fail &str
|
|
&lab bcc @ok
|
|
pha
|
|
pea @str>>16
|
|
pea @str
|
|
_SysFailMgr
|
|
brk $ea
|
|
@str str.b &str
|
|
@ok
|
|
mend
|
|
|
|
;
|
|
; everything below here will be clobbered.
|
|
;
|
|
startup proc
|
|
;
|
|
; load the catalog extents
|
|
; lookup :system, :system:driver, :system:fsts, system:system:setup folders to save time later?
|
|
;
|
|
;
|
|
|
|
; read :system:start.gsos, load into memory @ $6800
|
|
; aux type is stored in auxtype
|
|
|
|
with zp, data
|
|
|
|
; assume 16-bit, etc.
|
|
|
|
; unit still active from before, for now....
|
|
|
|
; stx slot
|
|
sty vector
|
|
; sta unit
|
|
|
|
lda #0
|
|
tcd
|
|
ldx #$1ff
|
|
txs
|
|
|
|
|
|
if not __smartport__ then
|
|
lda #buffer
|
|
sta pro.dataBuffer
|
|
short m
|
|
lda #1
|
|
sta pro.cmd
|
|
long m
|
|
endif
|
|
|
|
with HFSMasterDirectoryBlock
|
|
lda #2
|
|
ldx #0
|
|
jsr read_block_abs
|
|
; shouldn't fail.
|
|
lda buffer+drAlBlSt
|
|
xba
|
|
sta startingBlock
|
|
|
|
lda buffer+drAlBlkSiz+1
|
|
xba
|
|
lsr a ; / 2
|
|
sta blockMultiplier
|
|
|
|
; 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?
|
|
|
|
endwith
|
|
|
|
; find the root node.
|
|
lda #0
|
|
jsr read_cat_block
|
|
|
|
with BTHeaderRec
|
|
lda buffer+BTNodeDescriptor.sizeof+rootNode+2
|
|
xba
|
|
sta cat_root
|
|
|
|
;
|
|
; lookup SYSTEM
|
|
;
|
|
lda #kHFSRootFolderID
|
|
sta target_parent
|
|
lda #kHFSRootFolderID>>16
|
|
stz target_parent+2
|
|
ldx #30
|
|
@zloop stz target_str,x
|
|
dex
|
|
dex
|
|
bpl @zloop
|
|
|
|
ldx #14-2
|
|
sloop
|
|
lda sys,x
|
|
sta target_str_len,x
|
|
dex
|
|
dex
|
|
bpl sloop
|
|
|
|
jsr cat_lookup
|
|
ifc_fail 'Missing System folder. Error=$'
|
|
|
|
; also check if dir?
|
|
|
|
lda file_id
|
|
sta system_id
|
|
sta target_parent
|
|
lda file_id+2
|
|
sta system_id+2
|
|
sta target_parent+2
|
|
|
|
; lookup System:FSTs
|
|
|
|
ldx #14-2
|
|
floop
|
|
lda fsts,x
|
|
sta target_str_len,x
|
|
dex
|
|
dex
|
|
bpl floop
|
|
|
|
jsr cat_lookup
|
|
ifc_fail 'Missing System:FSTs folder. Error=$'
|
|
|
|
; also check if dir?
|
|
|
|
lda file_id
|
|
sta fsts_id
|
|
lda file_id+2
|
|
sta fsts_id+2
|
|
|
|
; lookup System:Drivers
|
|
|
|
ldx #14-2
|
|
dloop
|
|
lda drv,x
|
|
sta target_str_len,x
|
|
dex
|
|
dex
|
|
bpl dloop
|
|
|
|
jsr cat_lookup
|
|
ifc_fail 'Missing System:Drivers folder. Error=$'
|
|
|
|
; also check if dir?
|
|
|
|
lda file_id
|
|
sta drivers_id
|
|
lda file_id+2
|
|
sta drivers_id+2
|
|
|
|
|
|
; lookup System:Start.GS.OS
|
|
ldx #14-2
|
|
@gloop
|
|
lda gsos,x
|
|
sta target_str_len,x
|
|
dex
|
|
dex
|
|
bpl @gloop
|
|
|
|
jsr cat_lookup
|
|
ifc_fail 'Missing System:Start.GS.OS. Error=$'
|
|
|
|
|
|
|
|
read
|
|
stz r0
|
|
lda blocks
|
|
beq bad
|
|
|
|
lda #$6800
|
|
if __smartport__ then
|
|
sta sp.dataBuffer
|
|
else
|
|
sta pro.dataBuffer
|
|
endif
|
|
|
|
@loop lda r0
|
|
jsr read_file_block
|
|
bcs bad
|
|
; clc
|
|
lda #512
|
|
if __smartport__ then
|
|
adc sp.dataBuffer
|
|
sta sp.dataBuffer
|
|
else
|
|
adc pro.dataBuffer
|
|
sta pro.dataBuffer
|
|
endif
|
|
inc r0
|
|
dec blocks
|
|
bne @loop
|
|
|
|
|
|
lda at
|
|
sta auxtype
|
|
|
|
lda #buffer
|
|
if __smartport__ then
|
|
sta sp.dataBuffer
|
|
else
|
|
sta pro.dataBuffer ; kind of important...
|
|
endif
|
|
|
|
lda #0
|
|
jmp $6800
|
|
|
|
bad pha
|
|
pea @str>>16
|
|
pea @str
|
|
_SysFailMgr
|
|
brk $ea
|
|
@str str.b 'Error reading Start.GS.OS. Error=$'
|
|
|
|
|
|
; buffered out to same length.
|
|
sys str.w 'SYSTEM'
|
|
dcb.b 6,0
|
|
fsts str.w 'FSTS'
|
|
dcb. 8,0
|
|
drv str.w 'DRIVERS'
|
|
dcb.b 5,0
|
|
gsos str.w 'START.GS.OS'
|
|
dcb.b 1,0
|
|
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
|