work towards wildcard support and file loading in CBDOS

This commit is contained in:
FeralChild64 committed 2021-02-18 16:28:48 +01:00
1 parent 53ab124dbc
commit 8eb40537ab
3 files changed
+263 -7

No files matched your search

+21 -6
View File
@@ -7,6 +7,13 @@
; - additional 16KB RAM is reserved for DOS too ($14000-$17FFF), and can be banked-in if needed
;
; Temporary storage locations
;
!addr FS_HVSR_DIRENT = $1000
;
; Page start+0
;
@@ -41,7 +48,7 @@
!addr par_LDA_nnnn_Y = $8015 ; - 2 bytes; address in buffer, ram disk
!addr code_RTS_04 = $8017 ; - RTS instruction
; Parameters for utilities
; Parameters for utilities/helkpers
!addr PAR_TRACK = $8018 ; track number for status/error
!addr PAR_SECTOR = $8019 ; sector number for status/error
@@ -49,14 +56,18 @@
!addr PAR_FSIZE_BYTES = $801A ; 4 bytes - file size in bytes
!addr PAR_FSIZE_BLOCKS = $801E ; 2 bytes - file size in blocks
!addr PAR_FTYPE = $801F ; bits 0-5 - type, bits 6-7 - protected, closed
!addr PAR_FNAME = $8020 ; 16 bytes - filename, filled with $A0
!addr PAR_FPATTERN = $8030 ; 16 bytes - pattern to match, filled with $A0
; Various temporary data
!addr XX_DIR_PHASE = $8020 ; directory output phase, values deponds on device driver, but 0 = not reading
!addr SD_DIR_PHASE = $8020 ; - SD card
!addr FD_DIR_PHASE = $8021 ; - floppy
!addr RD_DIR_PHASE = $8022 ; - ram disk
!addr XX_DIR_PHASE = $8040 ; directory output phase, values deponds on device driver, but 0 = not reading
!addr SD_DIR_PHASE = $8040 ; - SD card
!addr FD_DIR_PHASE = $8041 ; - floppy
!addr RD_DIR_PHASE = $8042 ; - ram disk
; Free space: $8023-$8063
; Free space: $8043-$8063
!addr SD_ACPTR_helper = $8052 ; subroutine in RAM to read a byte
!addr code_LDA_01 = $8052 ; - LDA instruction
@@ -103,6 +114,10 @@
!addr FD_STATUS_STR = $80A0 ; status string for floppy drive, terminated by 0
!addr RD_STATUS_STR = $80D0 ; status string for ram disk, terminated by 0
;
; Further pages
;
!addr SD_CMDFN_BUF = $8100 ; buffer for command and/or file name, 128 bytes, SD card
!addr FD_CMDFN_BUF = $8180 ; buffer for command and/or file name, 128 bytes, floppy
!addr RD_CMDFN_BUF = $8200 ; buffer for command and/or file name, 128 bytes, ram disk
+1 -1
View File
@@ -322,7 +322,7 @@ fs_hvsr_read_dir:
fs_hvsr_read_dir_blocksfree:
; Set pointer to '65535 BLOCKS FREE.' line
; Set pointer to 'BLOCKS FREE.' line
; XXX determine free space
@@ -0,0 +1,241 @@
;
; Hypervisor virtual filesystem - helper routine to get the next directory entry
;
; Fills-in: PAR_FNAME, PAR_FTYPE, PAR_FSIZE_BYTES
; NOTE: overrides page pointed by FS_HVSR_DIRENT!
; XXX work-in-progress, this should be used within directory reading code
fs_hvsr_util_nextdirentry:
; Clear the page which will be used
ldx #$00
txa
@lpclear:
sta FS_HVSR_DIRENT, x
inx
bne @lpclear
; Ask the hypervisor to read the next dirent structure
ldx SD_DESC ; directory descriptor XXX rename to FS_HVSR_DESC
ldy #>FS_HVSR_DIRENT ; target page number
lda #$14 ; dos_readdir
sta HTRAP00
+nop
+bcc @fail
; Reading entry succeeded, try to decode it. Important dirent fileds:
; - $00-$3F - file name
; - $40 - file name length
; - $52-$55 - file length
; - $56-$57 - file type ($10 = dir, $20 = regular) and attributes ($01 for read-only)
;
; Preprocess/validate the filename
;
ldx FS_HVSR_DIRENT+$40 ; file name length
beq fs_hvsr_util_nextdirentry ; do not even try for empty file name
cmp #20
bcs fs_hvsr_util_nextdirentry ; if longer than 16 characters + dot + extension - also skip this one
dex
@lpname:
lda FS_HVSR_DIRENT,x
cmp #$22
beq fs_hvsr_util_nextdirentry ; quotation mark is illegal
cmp #$2A
beq fs_hvsr_util_nextdirentry ; asterisk is illegal, it is used for filtering
cmp #$3F
beq fs_hvsr_util_nextdirentry ; the question mark - in the MS-DOS world it is illegal
cmp #$20
bcc fs_hvsr_util_nextdirentry ; control characters are not allowed
cmp #$5B
bcc @lpname_next ; up to PETSCII 'Z' is OK
cmp #$61
bcc fs_hvsr_util_nextdirentry ; some characters are not allowed
cmp #$7E
bne @lpname_1
lda #$A6 ; replace tilde / pi with something more sane
bra @lpname_store_next
@lpname_1:
cmp #$7B
bcs fs_hvsr_util_nextdirentry ; PETSCII-art and control characters are illegal
clc
sbc #$20 ; make everything the same case
@lpname_store_next:
sta FS_HVSR_DIRENT,x ; use this when file name has to be adapted
@lpname_next:
dex
bpl @lpname
;
; Determine type (file/directory)
;
lda FS_HVSR_DIRENT+$56
tax
and #$FE
beq @entity_file ; workaround for older hypervisors
and #$20
bne @entity_file ; branch on file
txa
and #$10
beq fs_hvsr_util_nextdirentry ; this type is unknown
@entity_dir:
; Once again validate the name length, with more precise information
lda FS_HVSR_DIRENT+$40
cmp #$11
bcs fs_hvsr_util_nextdirentry ; skip entry if file name longer than 16 characters
; Set the type to directory
lda #$05
bra @detect_attributes
@entity_file:
; Once again validate the name length, with more precise information
lda FS_HVSR_DIRENT+$40
sec
sbc #$04 ; strip 4 bytes - for dot and extension
bmi fs_hvsr_util_nextdirentry ; if name too short, try next entry
beq fs_hvsr_util_nextdirentry ; if name too short, try next entry
sta FS_HVSR_DIRENT+$40 ; store corrected file name length
tax
; Make sure there is a dot marking the start of a 3-byte extension
lda FS_HVSR_DIRENT, x
cmp #$2E
+bne fs_hvsr_util_nextdirentry
;
; Detect file type by extension
;
inx
ldy #$00
@lpext:
lda FS_HVSR_DIRENT+0, x
cmp dir_types+0, y
bne @lpext_next
lda FS_HVSR_DIRENT+1, x
cmp dir_types+1, y
bne @lpext_next
lda FS_HVSR_DIRENT+2, x
cmp dir_types+2, y
beq @lpext_found
@lpext_next:
iny
iny
iny
iny
cpy #(dir_types__end - dir_types)
bcc @lpext
jmp fs_hvsr_util_nextdirentry ; file extension not detected
@lpext_found:
cpy #$10
+beq fs_hvsr_util_nextdirentry ; file extension 'DIR' does not mean this is a directory
tya
asr ; convert the result to CBM-compatible value
asr
inc
cmp #$06 ; mark some file types (not SEQ/PRG/USR/REL/DIR) as read-only
bcc @detect_attributes
ora #$40
@detect_attributes:
ora #$80 ; mark the file as closed, FAT32 does not have a 'not closed' attribute
sta PAR_FTYPE
lda FS_HVSR_DIRENT+$56 ; also apply read-only attribute from FAT32
and #$01
beq @copy_size
lda PAR_FTYPE
ora #$40
sta PAR_FTYPE
@copy_size:
; Copy the file size
ldx #$03
@lpsize:
lda FS_HVSR_DIRENT+$52,x ; copy file size in byytes
sta PAR_FSIZE_BYTES,x
dex
bpl @lpsize
@copy_name:
; Last, but not least - copy file name
lda #$A0 ; fill-in empty bytes with $A0, to simulate CBM file system
ldx #$0F
@lpname_cpy:
cpx FS_HVSR_DIRENT+$40
bcs @lpname_fill
lda FS_HVSR_DIRENT, x
@lpname_fill:
sta PAR_FNAME,x
dex
bpl @lpname_cpy
; All done
clc
rts
@fail:
; Reading next entry failed, this is the end
; XXX check error code
sec
rts