Files
open-roms/src/dos_m65/dev_floppy/fs_1581_read_dir.s
T
2021-03-05 22:37:14 +01:00

324 lines
5.0 KiB
ArmAsm

;
; Hypervisor virtual filesystem - reading directory
;
fs_1581_read_dir_open:
; Try to read track 40, sector 0 (disk header)
lda #40
sta PAR_TRACK
lda #$00
sta PAR_SECTOR
jsr dev_fd_util_readsector ; XXX handle read errors
; Create the first directory listing entry (title, id)
ldx #$1F ; first fetch the template
@lp1:
lda dir_hdr,x
sta FD_DIRENT_BUF,x
dex
bpl @lp1
ldx #$0F ; file name
@lp2:
lda SHARED_BUF_1+$04,x
sta FD_DIRENT_BUF+$08,x
dex
bpl @lp2
lda SHARED_BUF_1+$16 ; disk ID XXX test this on a disk with ID
cmp #$A0
beq @skip1
sta FD_DIRENT_BUF+$1A
@skip1:
lda SHARED_BUF_1+$17
cmp #$A0
beq @skip2
sta FD_DIRENT_BUF+$1B
@skip2:
lda SHARED_BUF_1+$19 ; dos version
sta FD_DIRENT_BUF+$1D
lda SHARED_BUF_1+$1A
sta FD_DIRENT_BUF+$1E
; Provide pointer to the header
lda #$20
sta FD_ACPTR_LEN+0
lda #$00
sta FD_ACPTR_LEN+1
lda #<FD_DIRENT_BUF
sta FD_ACPTR_PTR+0
lda #>FD_DIRENT_BUF
sta FD_ACPTR_PTR+1
; Set directory phase to 'file name'
lda #$01
sta FD_DIR_PHASE
; Copy 1st BAM sector to the cache
ldx #$00
@lp3:
lda SHARED_BUF_1+$100, x
sta FD_BAM_CACHE_0,x
inx
bne @lp3
; Load the next pair of sectors
lda #$02
sta PAR_SECTOR
jsr dev_fd_util_readsector ; XXX handle read errors
; Copy 2nd BAM sector to the cache
ldx #$00
@lp4:
lda SHARED_BUF_1, x
sta FD_BAM_CACHE_0+$100,x
inx
bne @lp4
; Set variables to point to the 1st directory entry in the 2nd sector of the buffer
lda #$08
sta FD_DIRENT
; Make sure the 1st sector in buffer points to 2nd one
lda #40
sta SHARED_BUF_1+0
lda #03
sta SHARED_BUF_1+1
; End
jmp dos_EXIT_CLC
fs_1581_read_dir:
lda FD_DIRENT
; If first entry within sector - make sure it is present within the buffer
cmp #$08
beq @get_sector_lo
cmp #$10
+beq @get_sector_hi
; FALLTROUGH
@cont:
; Set address of the RAW directory entry
ldy #>SHARED_BUF_1
sty par_LDA_nnnn_Y+1
asl
asl
asl
asl
asl
sta par_LDA_nnnn_Y+0
bcc @1
inc par_LDA_nnnn_Y+1
@1:
; Set next directory entry
inc FD_DIRENT
; Copy data to parameter variables
; XXX most likely copying is not necessary (compare all CBM and CMD filesystems) -
; XXX just make the hypervisor file system emulate these structures
ldy #$02 ; start from determining file type
jsr code_LDA_nnnn_Y
beq fs_1581_read_dir ; ignore deleted files (but allow DEL files in some cases)
tax
and #%00111111 ; for checking, filter out special bits
cmp #$06
bcs fs_1581_read_dir ; ignore unknown file types
stx PAR_FTYPE
ldy #$1E ; now get file size in blocks
jsr code_LDA_nnnn_Y
sta PAR_FSIZE_BLOCKS+0
iny
jsr code_LDA_nnnn_Y
sta PAR_FSIZE_BLOCKS+1
ldy #$05 ; copy the file name
@lp1:
jsr code_LDA_nnnn_Y
sta PAR_FNAME-5,y
iny
cpy #$15
bne @lp1
; Prepare output entry, starting from XX_DIRENT_BUF + initial offset
jsr util_dir_filesize_blocks
ldx #(FD_DIRENT_BUF - XX_DIRENT_BUF)
ldx #$30
jsr util_dir_basic
; Provide pointers and length
sta FD_ACPTR_LEN+1
txa
sec
sbc #$30
sta FD_ACPTR_LEN+0
lda #<(FD_DIRENT_BUF)
sta FD_ACPTR_PTR+0
lda #>(FD_DIRENT_BUF)
sta FD_ACPTR_PTR+1
clc
rts
@get_sector_lo:
; Check if this was the last sector
lda SHARED_BUF_1+0
beq fs_1581_read_dir_blocksfree
lda SHARED_BUF_1+1
cmp #$FF
beq fs_1581_read_dir_blocksfree
; Transition from 1st half of the buffer, to (possibly) the second one
lda SHARED_BUF_1+0
cmp BUFTAB_TRACK+1
bne @get_sector_lo_next
lda SHARED_BUF_1+1
dec
cmp BUFTAB_SECTOR+1
bne @get_sector_lo_next
; It's OK, we can transition to the upper half of the buffer
lda FD_DIRENT
jmp @cont
@get_sector_lo_next:
lda SHARED_BUF_1+0
sta PAR_TRACK
lda SHARED_BUF_1+1
sta PAR_SECTOR
bra @get_sector_common
@get_sector_hi:
; Check if this was the last sector
lda SHARED_BUF_1+$100+0
beq fs_1581_read_dir_blocksfree
lda SHARED_BUF_1+$100+1
cmp #$FF
beq fs_1581_read_dir_blocksfree
; Load new sector
lda SHARED_BUF_1+$100+0
sta PAR_TRACK
lda SHARED_BUF_1+$100+1
sta PAR_SECTOR
@get_sector_common:
jsr dev_fd_util_readsector ; XXX handle read errors
; Set new FD_DIRENT
lda PAR_SECTOR
and #$01
beq @2
lda #$08
@2:
sta FD_DIRENT
jmp @cont
fs_1581_read_dir_blocksfree:
; Copy the 'BLOCKS FREE' line
ldx #$13
@lp1:
lda dir_end, x
sta FD_DIRENT_BUF, x
dex
bpl @lp1
; Calculate free blocks from the BAM
ldx #$10
@lp2:
lda FD_BAM_CACHE_0+$100,x
jsr @sub_free_add
cpx #$FA
beq @lp2_end
lda FD_BAM_CACHE_0+$000,x
jsr @sub_free_add
inx
inx
inx
inx
inx
inx
bra @lp2
@lp2_end:
; Set pointer and length
lda #$13
sta FD_ACPTR_LEN+0
lda #$00
sta FD_ACPTR_LEN+1
lda #<FD_DIRENT_BUF
sta FD_ACPTR_PTR+0
lda #>FD_DIRENT_BUF
sta FD_ACPTR_PTR+1
; Mark end of directory
lda #$00
sta FD_DIR_PHASE
clc
rts
@sub_free_add:
; Helper routine to calculate free blocks
clc
adc FD_DIRENT_BUF+2
sta FD_DIRENT_BUF+2
bcc @noinc
inc FD_DIRENT_BUF+3
@noinc:
rts