diff --git a/src/dos_m65/,aliases_dos.s b/src/dos_m65/,aliases_dos.s index dc3512f1..b4717c43 100644 --- a/src/dos_m65/,aliases_dos.s +++ b/src/dos_m65/,aliases_dos.s @@ -122,5 +122,10 @@ !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 SD_DIRENT = $8280 ; 256 byte buffer for 'dirent' structure - !addr SD_DESC = $8380 ; current file descriptor + !addr XX_DIR_ENTRY = $8280 ; directory entry in BASIC format + !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 diff --git a/src/dos_m65/dev_sdcard/fs_hvsr_read_dir.s b/src/dos_m65/dev_sdcard/fs_hvsr_read_dir.s index 762f7f42..c7909470 100644 --- a/src/dos_m65/dev_sdcard/fs_hvsr_read_dir.s +++ b/src/dos_m65/dev_sdcard/fs_hvsr_read_dir.s @@ -49,272 +49,130 @@ fs_hvsr_read_dir_open: 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 - ; Content of the original memory location will be preserved - jsr fs_hvsr_dirent_prepare - - ldx SD_DESC ; directory descriptor - ldy #$10 ; target page number - - lda #$14 ; dos_readdir - sta HTRAP00 - +nop - - jsr fs_hvsr_dirent_swap ; processor status is preserved + jsr fs_hvsr_direntmem_prepare + jsr fs_hvsr_util_nextdirentry + jsr fs_hvsr_direntmem_restore ; processor status is preserved ; If nothing to read, output 'blocks free' +bcc fs_hvsr_read_dir_blocksfree - ; Dirent structure - important fields: - ; - $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 + ; Otherwise, convert the file length from bytes to blocks to display jsr util_dir_filesize_bytes - lda PAR_FSIZE_BLOCKS+0 - sta SD_DIRENT+$82 - lda PAR_FSIZE_BLOCKS+1 - sta SD_DIRENT+$83 + ; Prepare output entry, starting from XX_DIR_ENTRY + initial offset - lda #' ' - ldx #$04 ; indent number of blocks -@lpindent1: - dey - bmi @lpindent1_done - sta SD_DIRENT+$80, x + ldx #$00 ; offset for SD card unit + + lda #$01 ; link to the next line - dummy, will be regenerated by BASIC + sta XX_DIR_ENTRY, x + inx + sta XX_DIR_ENTRY, x 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 - sta SD_DIRENT+$80, x + sta XX_DIR_ENTRY, x ldy #$FF ; put file name @lp2: - inx iny - lda SD_DIRENT, y - sta SD_DIRENT+$80,x - bne @lp2 + lda PAR_FNAME, y + cmp #$A0 + beq @lp2_done + sta XX_DIR_ENTRY, x + inx + bra @lp2 + +@lp2_done: lda #$22 ; closing quote - sta SD_DIRENT+$80, x + sta XX_DIR_ENTRY, x inx - lda #' ' ; put spaces for indentation - ldy SD_DIRENT+$40 + ldy #$10 ; put spaces for indentation @lp3: - sta SD_DIRENT+$80, x + lda #' ' + sta XX_DIR_ENTRY, x 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: lda dir_types, y beq @lp4_done - sta SD_DIRENT+$80, x + sta XX_DIR_ENTRY, x inx iny bra @lp4 @lp4_done: - lda SD_DIRENT+$FE ; read-only mark (if needed) + lda PAR_FTYPE ; read-only mark (if needed) + and #$40 beq @skipro - sta SD_DIRENT+$80, x + sta XX_DIR_ENTRY, x inx @skipro: - lda #$00 - sta SD_DIRENT+$80, x + lda #$00 ; put end of the line + sta XX_DIR_ENTRY, x inx stx SD_ACPTR_LEN+0 sta SD_ACPTR_LEN+1 - lda #<(SD_DIRENT+$80) + lda #<(XX_DIR_ENTRY) sta SD_ACPTR_PTR+0 - lda #>(SD_DIRENT+$80) + lda #>(XX_DIR_ENTRY) sta SD_ACPTR_PTR+1 clc @@ -355,30 +213,29 @@ fs_hvsr_read_dir_blocksfree: ; Helper routines ; -fs_hvsr_dirent_prepare: +fs_hvsr_direntmem_prepare: ldx #$00 - txa @1: ldy $1000, x - sty SD_DIRENT, x - sta $1000, x + sty SD_MEMSHADOW, x inx bne @1 rts -fs_hvsr_dirent_swap: +fs_hvsr_direntmem_restore: php + ldx #$00 @1: - lda $1000, x - ldy SD_DIRENT, x - sta SD_DIRENT, x + ldy SD_MEMSHADOW, x sty $1000, x inx bne @1 + bne @1 + plp rts