rename, reduce, separate

renamed to reflect write support;
reduced code size a bit;
separated optional components into conditional blocks
This commit is contained in:
Peter Ferrie 2016-05-18 14:38:00 -07:00
parent 132a651249
commit 1a2d215114

View File

@ -1,15 +1,21 @@
;open/read/write binary file in ProDOS filesystem ;open/read/write binary file in ProDOS filesystem
;copyright (c) Peter Ferrie 2013-16 ;copyright (c) Peter Ferrie 2013-16
!cpu 6502 !cpu 6502
!to "prorts",plain !to "prorwts",plain
*=$800 *=$800
enable_floppy = 0 ;set to 1 to enable floppy drive support
override_adr = 0 ;set to 1 to require an explicit load address override_adr = 0 ;set to 1 to require an explicit load address
enable_write = 0 ;set to 1 to enable write support enable_write = 0 ;set to 1 to enable write support
;file must exist already and its size cannot be altered ;file must exist already and its size cannot be altered
;writes occur in multiples of block size (256 bytes for floppy, 512 bytes for HDD) ;writes occur in multiples of block size (256 bytes for floppy, 512 bytes for HDD)
allow_subdir = 0 ;set to 1 to allow opening subdirectories to access files
;note that if enable_floppy=1, then override_adr must be 1, or allow_subdir must be 0
;unless the reloc address is changed
!if enable_floppy=1 {
tmpsec = $3c tmpsec = $3c
reqsec = $3d reqsec = $3d
}
A1L = $3c A1L = $3c
A1H = $3d A1H = $3d
A2L = $3e A2L = $3e
@ -18,7 +24,9 @@
A3L = $40 A3L = $40
A3H = $41 A3H = $41
} }
!if enable_floppy=1 {
curtrk = $40 curtrk = $40
}
command = $42 ;ProDOS constant command = $42 ;ProDOS constant
unit = $43 ;ProDOS constant unit = $43 ;ProDOS constant
@ -39,28 +47,31 @@
ldrhi = $fa ;used if override_adr=1 ldrhi = $fa ;used if override_adr=1
namlo = $fb namlo = $fb
namhi = $fc namhi = $fc
!if enable_floppy=1 {
step = $fd ;state for stepper motor step = $fd ;state for stepper motor
tmptrk = $fe ;temporary copy of current track tmptrk = $fe ;temporary copy of current track
phase = $ff ;current phase for seek phase = $ff ;current phase for seek
!if enable_write=1 { !if enable_write=1 {
reloc = $bc00 reloc = $bc00
dirbuf = $ba00 dirbuf = $ba00
encbuf = $b900 encbuf = $b900
xlattbl = dataend } else { ;enable_write
} else {
reloc = $bd00 reloc = $bd00
dirbuf = $bb00 dirbuf = $bb00
}
} else { ;enable_floppy
reloc = $be00
dirbuf = $bc00
} }
init init jsr $fe93
jsr $fe93
jsr $fe89 jsr $fe89
lda $bf30 lda $bf30
sta x80_parms+1 sta x80_parms+1
sta unrunit+1 sta unrunit+1
and #$70 and #$70
sta $2b
pha pha
!if enable_floppy=1 {
ora #$80 ora #$80
sta unrseek+1 sta unrseek+1
ora #8 ora #8
@ -72,7 +83,7 @@ init
sta unrread1+1 sta unrread1+1
sta unrread2+1 sta unrread2+1
sta unrread3+1 sta unrread3+1
!if enable_write=1 { !if enable_write=1 {
sta unrread4+1 sta unrread4+1
sta unrread5+1 sta unrread5+1
sta unrread6+1 sta unrread6+1
@ -87,7 +98,8 @@ init
stx unrlatchin+1 stx unrlatchin+1
inx inx
stx unrlatchout+1 stx unrlatchout+1
} } ;enable_write
} ;enable_floppy
ldx #1 ldx #1
stx namlo stx namlo
inx inx
@ -174,8 +186,10 @@ ifoundname iny
dey dey
lda (A1L), y lda (A1L), y
tay tay
!if enable_floppy=1 {
sty unrblocklo+1 sty unrblocklo+1
stx unrblockhi+1 stx unrblockhi+1
}
sty unrhddblocklo+1 sty unrhddblocklo+1
stx unrhddblockhi+1 stx unrhddblockhi+1
plus03 sty x80_parms+4 plus03 sty x80_parms+4
@ -191,9 +205,9 @@ plus05 pla
ora #$c0 ora #$c0
sta slot+2 sta slot+2
sta unrentry+2 sta unrentry+2
!if enable_floppy=1 {
ldx #>unrelocdsk ldx #>unrelocdsk
ldy #<unrelocdsk ldy #<unrelocdsk
slot lda $cfff slot lda $cfff
sta unrentry+1 sta unrentry+1
php php
@ -206,20 +220,20 @@ copydrv stx A1H
inx inx
stx A2H stx A2H
sty A2L sty A2L
!if enable_write=1 { !if enable_write=1 {
inx inx
stx A3H stx A3H
sty A3L sty A3L
} }
ldy #0 ldy #0
minus03 lda (A1L), y minus03 lda (A1L), y
sta reloc, y sta reloc, y
lda (A2L), y lda (A2L), y
sta reloc+$100, y sta reloc+$100, y
!if enable_write=1 { !if enable_write=1 {
lda (A3L), y lda (A3L), y
sta reloc+$200, y sta reloc+$200, y
} }
iny iny
bne minus03 bne minus03
plp plp
@ -238,15 +252,27 @@ minus05 bcs plus06
bne minus05 bne minus05
tya tya
sta nibtbl, x sta nibtbl, x
!if enable_write=1 { !if enable_write=1 {
txa txa
ora #$80 ora #$80
sta xlattbl, y sta xlattbl, y
} }
iny iny
plus06 inx plus06 inx
bpl minus04 bpl minus04
plus07 rts plus07 rts
} else { ;enable_floppy
slot lda $cfff
sta unrentry+1
ldy #0
- lda unrelochdd, y
sta reloc, y
lda unrelochdd+$100, y
sta reloc+$100, y
iny
bne -
rts
}
c7_parms !byte 1 c7_parms !byte 1
!word $200 !word $200
@ -254,17 +280,18 @@ c7_parms !byte 1
x80_parms !byte 3, $d1 x80_parms !byte 3, $d1
!word readbuff, 2 !word readbuff, 2
!if enable_floppy=1 {
unrelocdsk unrelocdsk
!pseudopc reloc { !pseudopc reloc {
opendir ;read volume directory key block opendir ;read volume directory key block
!if enable_write=1 { !if enable_write=1 {
ldx #1 ldx #1
stx command stx command
dex dex
} else { } else {
ldx #0 ldx #0
} }
stx adrlo stx adrlo
stx secsize1 stx secsize1
unrblocklo=unrelocdsk+(*-reloc) unrblocklo=unrelocdsk+(*-reloc)
@ -295,11 +322,13 @@ nextent ldy #0
beq plus10 beq plus10
!if allow_subdir=1 {
;subdirectory entries are seedlings ;subdirectory entries are seedlings
;but we need to distinguish between them later ;but we need to distinguish between them later
cmp #$d0 cmp #$d0
beq savetype beq savetype
}
;watch for seedling and saplings only ;watch for seedling and saplings only
@ -308,8 +337,13 @@ nextent ldy #0
;remember type ;remember type
savetype asl savetype
!if allow_subdir=1 {
asl asl
asl
} else {
cmp #$20
}
php php
;match name lengths before attempting to match names ;match name lengths before attempting to match names
@ -362,21 +396,21 @@ foundname iny
dex dex
bne minus06 bne minus06
!if enable_write=1 { !if enable_write=1 {
ldy reqcmd ldy reqcmd
dey dey
beq plus81x beq plus13
;round requested size up to nearest sector ;round requested size up to nearest sector
;and cache requested size if writing ;and cache requested size if writing
ldx sizehi ldx sizehi
beq plus80x beq plus12
lda sizelo lda sizelo
beq plus81x beq plus13
plus80x inx plus12 inx
plus81x plus13
} }
;cache EOF (file size) ;cache EOF (file size)
@ -387,44 +421,50 @@ plus81x
lda (A1L), y lda (A1L), y
sta sizehi sta sizehi
!if enable_write=1 { !if enable_write=1 {
ldy reqcmd ldy reqcmd
dey dey
beq plus84x beq plus16
;round file size up to nearest sector ;round file size up to nearest sector
;and check against requested size if writing ;and check against requested size if writing
lda sizehi lda sizehi
beq plus82x beq plus14
lda sizelo lda sizelo
beq plus83x beq plus15
plus82x lda #0 plus14 lda #0
sta sizelo sta sizelo
inc sizehi inc sizehi
;set read size to min(length, requested size) ;set read size to min(length, requested size)
plus83x cpx sizehi plus15 cpx sizehi
bcs plus84x bcs plus16
stx sizehi stx sizehi
plus84x plus16
} }
;cache AUX_TYPE (load offset for binary files) ;cache AUX_TYPE (load offset for binary files)
!if override_adr=0 { !if override_adr=0 {
!if allow_subdir=1 {
pla pla
tax tax
} else {
plp
}
ldy #$1f ldy #$1f
lda (A1L), y lda (A1L), y
pha pha
iny iny
lda (A1L), y lda (A1L), y
pha pha
!if allow_subdir=1 {
txa txa
pha pha
} }
}
;cache KEY_POINTER (loaded backwards) ;cache KEY_POINTER (loaded backwards)
;and construct single-entry index block in case of seedling ;and construct single-entry index block in case of seedling
@ -442,41 +482,51 @@ plus84x
;read index block in case of sapling ;read index block in case of sapling
!if allow_subdir=1 {
plp plp
bpl plus13 bpl plus17
php php
jsr readdirsec jsr readdirsec
plp plp
} else {
!if override_adr=1 {
plp
}
bcc plus17
jsr readdirsec
}
;restore load offset ;restore load offset
plus13 plus17
!if override_adr=0 { !if override_adr=0 {
pla pla
tax tax
pla pla
} else { } else {
ldx ldrhi ldx ldrhi
lda ldrlo lda ldrlo
} }
!if enable_write=1 { !if enable_write=1 {
ldy reqcmd ldy reqcmd
} }
!if allow_subdir=1 {
;check file type and fake size and load address for subdirectories ;check file type and fake size and load address for subdirectories
bcc plus14 bcc plus18
lda #2 lda #2
sta sizehi sta sizehi
ldx #>dirbuf ldx #>dirbuf
lda #<dirbuf lda #<dirbuf
!if enable_write=1 { !if enable_write=1 {
ldy #1 ldy #1
} }
plus14 plus18
!if enable_write=1 { }
!if enable_write=1 {
sty command sty command
} }
sta adrlo sta adrlo
stx adrhi stx adrhi
lda #0 lda #0
@ -487,10 +537,10 @@ plus14
readfile lda sizelo readfile lda sizelo
ldx sizehi ldx sizehi
cpx #2 cpx #2
bcc plus15 bcc plus19
lda #0 lda #0
ldx #2 ldx #2
plus15 sta secsize1 plus19 sta secsize1
stx secsize2 stx secsize2
;fetch data block and read it ;fetch data block and read it
@ -558,9 +608,9 @@ seekread pha
ldy #0 ldy #0
lda secsize2 lda secsize2
bne plus16 bne plus20
ldy secsize1 ldy secsize1
plus16 sty secsize plus20 sty secsize
dec secsize2 dec secsize2
jsr readadr jsr readadr
@ -591,11 +641,11 @@ checksec jsr cmpsec
inc reqsec inc reqsec
cmpsec cmpsec
!if enable_write=1 { !if enable_write=1 {
ldy command ldy command
dey dey
bne encsec bne encsec
} }
cmpsecrd jsr readadr cmpsecrd jsr readadr
cmp reqsec cmp reqsec
bne cmpsecrd bne cmpsecrd
@ -635,7 +685,7 @@ minus10 inx
bne minus10 bne minus10
rts rts
!if enable_write=1 { !if enable_write=1 {
encsec iny encsec iny
minus11 ldx #0 minus11 ldx #0
minus12 dey minus12 dey
@ -736,7 +786,7 @@ unrlatch3=unrelocdsk+(*-reloc)
unrread8=unrelocdsk+(*-reloc) unrread8=unrelocdsk+(*-reloc)
ora $c0ec ora $c0ec
rts rts
} }
;no tricks here, just the regular stuff ;no tricks here, just the regular stuff
@ -779,26 +829,26 @@ copy_cur lda curtrk
sec sec
sbc phase sbc phase
beq seekret beq seekret
bcs plus17 bcs plus21
eor #$ff eor #$ff
inc curtrk inc curtrk
bcc plus18 bcc plus22
plus17 sbc #1 plus21 sbc #1
dec curtrk dec curtrk
plus18 cmp step plus22 cmp step
bcc plus19 bcc plus23
lda step lda step
plus19 cmp #8 plus23 cmp #8
bcs plus20 bcs plus24
tay tay
sec sec
plus20 lda curtrk plus24 lda curtrk
ldx step1, y ldx step1, y
bne plus21 bne plus25
minus24 clc minus24 clc
lda tmptrk lda tmptrk
ldx step2, y ldx step2, y
plus21 stx tmpsec plus25 stx tmpsec
and #3 and #3
rol rol
tax tax
@ -819,7 +869,13 @@ step2 !byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c
nibtbl = * nibtbl = *
bit2tbl = nibtbl+128 bit2tbl = nibtbl+128
!if enable_write=1 {
xlattbl = bit2tbl+86
dataend = xlattbl+64
} else {
dataend = bit2tbl+86 dataend = bit2tbl+86
}
}
} }
unrelochdd unrelochdd
@ -834,9 +890,11 @@ unrhddblockhi=unrelochdd+(*-reloc)
ldx #0 ldx #0
jsr hddreaddirsec jsr hddreaddirsec
!if enable_floppy=1 {
!if (*-hddopendir) < (readdir-opendir) { !if (*-hddopendir) < (readdir-opendir) {
;essential padding to match offset with floppy version ;essential padding to match offset with floppy version
!fill (readdir-opendir)-(*-hddopendir), $ea !fill (readdir-opendir)-(*-hddopendir), $ea
}
} }
;include volume directory header in count ;include volume directory header in count
@ -859,23 +917,30 @@ hddnextent ldy #0
;skip deleted entries without counting ;skip deleted entries without counting
beq plus24 beq plus28
!if allow_subdir=1 {
;subdirectory entries are seedlings ;subdirectory entries are seedlings
;but we need to distinguish between them later ;but we need to distinguish between them later
cmp #$d0 cmp #$d0
beq hddsavetype beq hddsavetype
}
;watch for seedling and saplings only ;watch for seedling and saplings only
cmp #$30 cmp #$30
bcs plus23 bcs plus27
;remember type ;remember type
hddsavetype asl hddsavetype
!if allow_subdir=1 {
asl asl
asl
} else {
cmp #$20
}
php php
;match name lengths before attempting to match names ;match name lengths before attempting to match names
@ -883,7 +948,7 @@ hddsavetype asl
lda (A1L), y lda (A1L), y
and #$0f and #$0f
cmp (namlo), y cmp (namlo), y
bne plus22 bne plus26
tax tax
iny iny
minus27 lda (A1L), y minus27 lda (A1L), y
@ -892,8 +957,8 @@ minus27 lda (A1L), y
;match failed, check if any directory entries remain ;match failed, check if any directory entries remain
plus22 plp plus26 plp
plus23 inc A2H plus27 inc A2H
lda A2H lda A2H
cmp entries cmp entries
@ -903,16 +968,16 @@ plus23 inc A2H
;move to next directory in this block, if possible ;move to next directory in this block, if possible
plus24 clc plus28 clc
lda A1L lda A1L
adc #$27 adc #$27
sta A1L sta A1L
bcc plus25 bcc plus29
;there can be only one page crossed, so we can increment instead of adc ;there can be only one page crossed, so we can increment instead of adc
inc A1H inc A1H
plus25 inc A2L plus29 inc A2L
lda A2L lda A2L
cmp #$0d cmp #$0d
bcc hddnextent bcc hddnextent
@ -928,10 +993,10 @@ hddfoundname iny
dex dex
bne minus27 bne minus27
!if enable_write=1 { !if enable_write=1 {
ldy reqcmd ldy reqcmd
dey dey
beq plus91x beq plus32
;round requested size up to nearest block ;round requested size up to nearest block
;and cache requested size if writing ;and cache requested size if writing
@ -939,15 +1004,15 @@ hddfoundname iny
lda sizehi lda sizehi
tax tax
lsr lsr
bcc plus89x bcc plus30
inx inx
plus89x cpx #2 plus30 cpx #2
bcc plus90x bcc plus31
lda sizelo lda sizelo
beq plus91x beq plus32
plus90x ldx #2 plus31 ldx #2
plus91x plus32
} }
;cache EOF (file size) ;cache EOF (file size)
@ -958,10 +1023,10 @@ plus91x
lda (A1L), y lda (A1L), y
sta sizehi sta sizehi
!if enable_write=1 { !if enable_write=1 {
ldy reqcmd ldy reqcmd
dey dey
beq plus94x beq plus36
;round file size up to nearest block ;round file size up to nearest block
;and check against requested size if writing ;and check against requested size if writing
@ -969,39 +1034,45 @@ plus91x
lda sizehi lda sizehi
tay tay
lsr lsr
bcc plus99x bcc plus33
iny iny
plus99x cpy #2 plus33 cpy #2
bcc plus92x bcc plus34
lda sizelo lda sizelo
beq plus93x beq plus35
plus92x lda #0 plus34 lda #0
sta sizelo sta sizelo
ldy #2 ldy #2
plus93x sty sizehi plus35 sty sizehi
;set read size to min(length, requested size) ;set read size to min(length, requested size)
cpx sizehi cpx sizehi
bcs plus94x bcs plus36
stx sizehi stx sizehi
plus94x plus36
} }
;cache AUX_TYPE (load offset for binary files) ;cache AUX_TYPE (load offset for binary files)
!if override_adr=0 { !if override_adr=0 {
!if allow_subdir=1 {
pla pla
tax tax
} else {
plp
}
ldy #$1f ldy #$1f
lda (A1L), y lda (A1L), y
pha pha
iny iny
lda (A1L), y lda (A1L), y
pha pha
!if allow_subdir=1 {
txa txa
pha pha
} }
}
;cache KEY_POINTER (loaded backwards) ;cache KEY_POINTER (loaded backwards)
;and construct single-entry index block in case of seedling ;and construct single-entry index block in case of seedling
@ -1019,53 +1090,61 @@ plus94x
;read index block in case of sapling ;read index block in case of sapling
!if allow_subdir=1 {
plp plp
bpl plus27 bpl plus37
php php
jsr hddreaddirsec jsr hddreaddirsec
plp plp
} else {
!if override_adr=1 {
plp
}
bcc plus37
jsr hddreaddirsec
}
;restore load offset ;restore load offset
plus27 plus37
!if override_adr=0 { !if override_adr=0 {
pla pla
tax tax
pla pla
} else { } else {
ldx ldrhi ldx ldrhi
lda ldrlo lda ldrlo
} }
!if allow_subdir=1 {
;check file type and fake size and load address for subdirectories ;check file type and fake size and load address for subdirectories
bcc plus28 bcc plus38
lda #2 ldy #2
sta sizehi sty sizehi
!if enable_write=1 {
dey
sty reqcmd
}
ldx #>dirbuf ldx #>dirbuf
lda #<dirbuf lda #<dirbuf
plus28 sta adrlo plus38
}
sta adrlo
stx adrhi stx adrhi
lda #0 lda #0
sta namlo sta namlo
!if enable_write=1 {
php
}
;set read size to min(length, $200) ;set read size to min(length, $200)
hddreadfile hddreadfile
!if enable_write=1 { !if enable_write=1 {
plp
php
ldy reqcmd ldy reqcmd
bcc plus29 sty command
ldy #1 }
plus29 sty command
}
lda sizehi lda sizehi
cmp #2 cmp #2
bcs plus30 bcs plus39
pha pha
lda #2 lda #2
sta sizehi sta sizehi
@ -1077,7 +1156,7 @@ plus29 sty command
sta adrhi sta adrhi
lda #0 lda #0
sta adrlo sta adrlo
plus30 php plus39 php
;fetch data block and read it ;fetch data block and read it
@ -1093,15 +1172,12 @@ plus30 php
dec sizehi dec sizehi
dec sizehi dec sizehi
bne hddreadfile bne hddreadfile
bcc plus31 bcc plus40
lda sizelo lda sizelo
bne hddreadfile bne hddreadfile
!if enable_write=1 {
plp
}
rts rts
plus31 pla plus40 pla
sta A1L sta A1L
pla pla
sta A1H sta A1H
@ -1109,15 +1185,15 @@ plus31 pla
dec adrhi dec adrhi
pla pla
tay tay
beq plus32 beq plus41
ldy #0 dey
minus28 lda (adrlo), y minus28 lda (adrlo), y
sta (A1L), y sta (A1L), y
iny iny
bne minus28 bne minus28
inc adrhi inc adrhi
inc A1H inc A1H
plus32 plus41
minus29 lda (adrlo), y minus29 lda (adrlo), y
sta (A1L), y sta (A1L), y
iny iny