324 lines
5.0 KiB
ArmAsm
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
|