; ; Hypervisor virtual filesystem - reading directory ; fs_hvsr_read_dir_open: ; Open the directory lda #$12 ; dos_opendir sta HTRAP00 +nop ; XXX handle read errors sta SD_DIR_DESC ; store directory descriptor XXX invent better name ; Reset status to OK lda #$00 jsr dos_status_00 ; Provide pointer to the header lda #$20 sta SD_ACPTR_LEN+0 lda #$00 sta SD_ACPTR_LEN+1 lda #dir_hdr_sd sta SD_ACPTR_PTR+1 ; Set directory phase to 'file name' lda #$01 sta SD_DIR_PHASE ; End jmp dos_EXIT fs_hvsr_read_dir: ; Read dirent structure into $1000 and then copy it to SD_DIRENT ; 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_DIR_DESC ; directory descriptor ldy #$10 ; target page number lda #$13 ; dos_readdir sta HTRAP00 +nop php jsr fs_hvsr_dirent_swap plp ; 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 ; - $51-$54 - file length ; - $55 - file type and attributes ; Validate/fix characters in file name ldx SD_DIRENT+$40 @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 #$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 #$7B bcs fs_hvsr_read_dir ; PETSCII-art and control characters are illegal clc sbc #$20 ; make everything the same case sta SD_DIRENT,x @lp1_next: dex bpl @lp1 inc $D020 ; Validate file name length ; XXX check for directory! 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 (+64 for read-only, +128 = damaged) lda SD_DIRENT, x cmp #$2E bne fs_hvsr_read_dir ; 3-character extension is required! ; XXX temporary; detect file type by extension instead ; Try to prepare output row, 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 lda #$00 ; XXX calculate length in blocks instead sta SD_DIRENT+$82 sta SD_DIRENT+$83 ldx #$04 ; XXX put correct amount of spaces instead lda #' ' sta SD_DIRENT+$80, x inx sta SD_DIRENT+$80, x lda #$22 ; opening quote sta SD_DIRENT+$80, x ldy #$FF ; put file name @lp2: inx iny lda SD_DIRENT, y sta SD_DIRENT+$80,x bne @lp2 inx lda #$22 ; closing quote sta SD_DIRENT+$80, x inx lda #' ' ; XXX put correct amount of spaces instead sta SD_DIRENT+$80, x inx sta SD_DIRENT+$80, x inx ; XXX put read-only mark if needed ldy #$03 ; XXX select proper file type instead lda dir_ext_01+0, y sta SD_DIRENT+$80, x inx lda dir_ext_01+1, y sta SD_DIRENT+$80, x inx lda dir_ext_01+2, y sta SD_DIRENT+$80, x inx ; No 'damaged' mark is needed here; put ending 0 and provide pointer lda #$00 sta SD_DIRENT+$80, x inx stx SD_ACPTR_LEN+0 sta SD_ACPTR_LEN+1 lda #<(SD_DIRENT+$80) sta SD_ACPTR_PTR+0 lda #>(SD_DIRENT+$80) sta SD_ACPTR_PTR+1 clc rts fs_hvsr_read_dir_blocksfree: ; Set pointer to '0 BLOCKS FREE.' line lda #$13 sta SD_ACPTR_LEN+0 lda #$00 sta SD_ACPTR_LEN+1 lda #dir_end sta SD_ACPTR_PTR+1 ; Mark end of directory lda #$00 sta SD_DIR_PHASE ; Close the directory within the hypervisor XXX maybe move it to close routine ldx SD_DIR_DESC lda #$14 ; dos_closedir sta HTRAP00 +nop clc rts ; ; Helper routines ; fs_hvsr_dirent_prepare: ldx #$00 txa @1: ldy $1000, x sty SD_DIRENT, x sta $1000, x inx bne @1 rts fs_hvsr_dirent_swap: php ldx #$00 @1: lda $1000, x ldy SD_DIRENT, x sta SD_DIRENT, x sty $1000, x inx bne @1 plp rts