more modularization in CBDOS, SD card directory display temporarily broken

This commit is contained in:
FeralChild64 committed 2021-02-22 18:39:42 +01:00
1 parent 8eb40537ab
commit 6ece4cbaf3
2 files changed
+85 -223

No files matched your search

+7 -2
View File
@@ -122,5 +122,10 @@
!addr FD_CMDFN_BUF = $8180 ; buffer for command and/or file name, 128 bytes, floppy !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 !addr RD_CMDFN_BUF = $8200 ; buffer for command and/or file name, 128 bytes, ram disk
!addr SD_DIRENT = $8280 ; 256 byte buffer for 'dirent' structure !addr XX_DIR_ENTRY = $8280 ; directory entry in BASIC format
!addr SD_DESC = $8380 ; current file descriptor !addr SD_DIR_ENTRY = $8280 ; - SD card
!addr FD_DIR_ENTRY = $82B0 ; - floppy
!addr RD_DIR_ENTRY = $82E0 ; - ram disk
!addr SD_MEMSHADOW = $8310 ; 256 byte buffer for preserving original memory content
!addr SD_DESC = $8410 ; current file descriptor
+78 -221
View File
@@ -49,272 +49,130 @@ fs_hvsr_read_dir_open:
fs_hvsr_read_dir: fs_hvsr_read_dir:
; Read dirent structure into $1000 and then copy it to SD_DIRENT ; Read dirent structure into $1000, process it, restore the memory content.
; Starting at $1000 VIC sees chargen, so this should be a safe place ; Starting at $1000 VIC sees chargen, so this should be a safe place
; Content of the original memory location will be preserved
jsr fs_hvsr_dirent_prepare jsr fs_hvsr_direntmem_prepare
jsr fs_hvsr_util_nextdirentry
ldx SD_DESC ; directory descriptor jsr fs_hvsr_direntmem_restore ; processor status is preserved
ldy #$10 ; target page number
lda #$14 ; dos_readdir
sta HTRAP00
+nop
jsr fs_hvsr_dirent_swap ; processor status is preserved
; If nothing to read, output 'blocks free' ; If nothing to read, output 'blocks free'
+bcc fs_hvsr_read_dir_blocksfree +bcc fs_hvsr_read_dir_blocksfree
; Dirent structure - important fields: ; Otherwise, convert the file length from bytes to blocks to display
; - $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)
; Retrieve read-only status, store mark in SD_DIRENT+$FE
lda SD_DIRENT+$56
and #$01
bne @rdonly
lda #$00
+skip_2_bytes_trash_nvz
@rdonly:
lda #'<'
sta SD_DIRENT+$FE
; Validate/fix characters in file name
ldx SD_DIRENT+$40
dex
@lp1:
lda SD_DIRENT,x
cmp #$22
beq fs_hvsr_read_dir ; quotation mark is illegal
cmp #$2A
beq fs_hvsr_read_dir ; asterisk is illegal, it is used for filtering
cmp #$3F
beq fs_hvsr_read_dir ; the question mark - in the MS-DOS world it is illegal
cmp #$20
bcc fs_hvsr_read_dir ; control characters are not allowed
cmp #$5B
bcc @lp1_next ; up to PETSCII 'Z' is OK
cmp #$61
bcc fs_hvsr_read_dir ; some characters are not allowed
cmp #$7E
bne @lp1_1
lda #$A6 ; replace tilde / pi with something more sane
bra @lp1_store_next
@lp1_1:
cmp #$7B
bcs fs_hvsr_read_dir ; PETSCII-art and control characters are illegal
clc
sbc #$20 ; make everything the same case
@lp1_store_next:
sta SD_DIRENT,x
@lp1_next:
dex
bpl @lp1
; Determine type (file/directory), store marker offset in SD_DIRENT+$FF
lda SD_DIRENT+$56
and #$FE
beq @cklen_file ; workaround for older hypervisors
and #$20
bne @cklen_file ; branch on file
lda SD_DIRENT+$56
and #$10
beq fs_hvsr_read_dir ; this type is unknown
@cklen_dir:
; Validate file name length (directories)
lda SD_DIRENT+$40
beq fs_hvsr_read_dir
cmp #$11
bcs fs_hvsr_read_dir
; Set type offset for directory in SD_DIRENT+$FF
lda #$10
bra @all_prepared
@cklen_file:
; Validate file name length (regular files)
lda SD_DIRENT+$40
sec
sbc #$04 ; strip 4 bytes - for dot and extension
sta SD_DIRENT+$40
+bmi fs_hvsr_read_dir ; if name too short, try next entry
+beq fs_hvsr_read_dir ; if name too short, try next entry
cmp #$11
+bcs fs_hvsr_read_dir ; if stripped name is 17 characters or longer, try the next entry
sta SD_DIRENT+$40 ; store corrected file name length
tax
; Detect file type
lda SD_DIRENT, x
cmp #$2E
+bne fs_hvsr_read_dir ; 3-character extension is required!
inx
ldy #$00
@lpdetect:
lda SD_DIRENT+0, x
cmp dir_types+0, y
bne @lpdetect_next
lda SD_DIRENT+1, x
cmp dir_types+1, y
bne @lpdetect_next
lda SD_DIRENT+2, x
cmp dir_types+2, y
beq @lpdetect_found
@lpdetect_next:
iny
iny
iny
iny
cpy #(dir_types__end - dir_types)
bcc @lpdetect
jmp fs_hvsr_read_dir ; file extension not detected
@lpdetect_found:
cpy #$10
+beq fs_hvsr_read_dir ; file extension 'DIR' does not mean this is a directory
tya
@all_prepared:
sta SD_DIRENT+$FF ; store offset to file type in SD_DIRENT+$FF
cmp #$14
bcc @noforcedro
lda #'<' ; for some file types, force the read-only flag
sta SD_DIRENT+$FE
@noforcedro:
; Prepare output entry, starting from SD_DIRENT+$80
lda #$01 ; link to the next line - dummy, will be regenerated by BASIC
sta SD_DIRENT+$80
sta SD_DIRENT+$81
ldx SD_DIRENT+$40 ; make sure file name is terminated by 0
lda #$00
sta SD_DIRENT, x
lda SD_DIRENT+$52 ; calculate file length in blocks to display
sta PAR_FSIZE_BYTES+0
lda SD_DIRENT+$53
sta PAR_FSIZE_BYTES+1
lda SD_DIRENT+$54
sta PAR_FSIZE_BYTES+2
lda SD_DIRENT+$55
sta PAR_FSIZE_BYTES+3
jsr util_dir_filesize_bytes jsr util_dir_filesize_bytes
lda PAR_FSIZE_BLOCKS+0 ; Prepare output entry, starting from XX_DIR_ENTRY + initial offset
sta SD_DIRENT+$82
lda PAR_FSIZE_BLOCKS+1
sta SD_DIRENT+$83
lda #' ' ldx #$00 ; offset for SD card unit
ldx #$04 ; indent number of blocks
@lpindent1: lda #$01 ; link to the next line - dummy, will be regenerated by BASIC
dey sta XX_DIR_ENTRY, x
bmi @lpindent1_done inx
sta SD_DIRENT+$80, x sta XX_DIR_ENTRY, x
inx inx
bra @lpindent1
@lpindent1_done: lda PAR_FSIZE_BLOCKS+0 ; store number of blocks
sta XX_DIR_ENTRY, x
inx
lda PAR_FSIZE_BLOCKS+1
sta XX_DIR_ENTRY, x
inx
lda #' ' ; indent file name
@lp1:
dey
bmi @lp1_done
sta XX_DIR_ENTRY, x
inx
bra @lp1
@lp1_done:
lda #$22 ; opening quote lda #$22 ; opening quote
sta SD_DIRENT+$80, x sta XX_DIR_ENTRY, x
ldy #$FF ; put file name ldy #$FF ; put file name
@lp2: @lp2:
inx
iny iny
lda SD_DIRENT, y lda PAR_FNAME, y
sta SD_DIRENT+$80,x cmp #$A0
bne @lp2 beq @lp2_done
sta XX_DIR_ENTRY, x
inx
bra @lp2
@lp2_done:
lda #$22 ; closing quote lda #$22 ; closing quote
sta SD_DIRENT+$80, x sta XX_DIR_ENTRY, x
inx inx
lda #' ' ; put spaces for indentation ldy #$10 ; put spaces for indentation
ldy SD_DIRENT+$40
@lp3: @lp3:
sta SD_DIRENT+$80, x lda #' '
sta XX_DIR_ENTRY, x
inx inx
iny
cpy #$11
bcc @lp3
; No 'damaged' mark make sense for this filesystem dey
lda PAR_FNAME, y
cmp #$A0
beq @lp3
ldy SD_DIRENT+$FF ; put file type lda PAR_FTYPE ; put 'damaged' mark if needed
bmi @damaged
lda #' '
+skip_2_bytes_trash_nvz
@damaged:
lda #'*'
sta XX_DIR_ENTRY, x
inx
lda PAR_FTYPE ; put file type
and #$3F
dec
asl
asl
tay
@lp4: @lp4:
lda dir_types, y lda dir_types, y
beq @lp4_done beq @lp4_done
sta SD_DIRENT+$80, x sta XX_DIR_ENTRY, x
inx inx
iny iny
bra @lp4 bra @lp4
@lp4_done: @lp4_done:
lda SD_DIRENT+$FE ; read-only mark (if needed) lda PAR_FTYPE ; read-only mark (if needed)
and #$40
beq @skipro beq @skipro
sta SD_DIRENT+$80, x sta XX_DIR_ENTRY, x
inx inx
@skipro: @skipro:
lda #$00 lda #$00 ; put end of the line
sta SD_DIRENT+$80, x sta XX_DIR_ENTRY, x
inx inx
stx SD_ACPTR_LEN+0 stx SD_ACPTR_LEN+0
sta SD_ACPTR_LEN+1 sta SD_ACPTR_LEN+1
lda #<(SD_DIRENT+$80) lda #<(XX_DIR_ENTRY)
sta SD_ACPTR_PTR+0 sta SD_ACPTR_PTR+0
lda #>(SD_DIRENT+$80) lda #>(XX_DIR_ENTRY)
sta SD_ACPTR_PTR+1 sta SD_ACPTR_PTR+1
clc clc
@@ -355,30 +213,29 @@ fs_hvsr_read_dir_blocksfree:
; Helper routines ; Helper routines
; ;
fs_hvsr_dirent_prepare: fs_hvsr_direntmem_prepare:
ldx #$00 ldx #$00
txa
@1: @1:
ldy $1000, x ldy $1000, x
sty SD_DIRENT, x sty SD_MEMSHADOW, x
sta $1000, x
inx inx
bne @1 bne @1
rts rts
fs_hvsr_dirent_swap: fs_hvsr_direntmem_restore:
php php
ldx #$00 ldx #$00
@1: @1:
lda $1000, x ldy SD_MEMSHADOW, x
ldy SD_DIRENT, x
sta SD_DIRENT, x
sty $1000, x sty $1000, x
inx inx
bne @1 bne @1
bne @1
plp plp
rts rts