collapseos/apps/basic/fs.asm

141 lines
2.5 KiB
NASM

; FS-related basic commands
; *** Variables ***
; Handle of the target file
.equ BFS_FILE_HDL BFS_RAMSTART
.equ BFS_RAMEND @+FS_HANDLE_SIZE
; Lists filenames in currently active FS
basFLS:
ld iy, .iter
jp fsIter
.iter:
ld a, FS_META_FNAME_OFFSET
call addHL
call printstr
jp printcrlf
basLDBAS:
call fsFindFN
ret nz
call bufInit
ld ix, BFS_FILE_HDL
call fsOpen
ld hl, 0
ld de, SCRATCHPAD
.loop:
ld ix, BFS_FILE_HDL
call fsGetB
jr nz, .loopend
inc hl
or a ; null? hum, weird. same as LF
jr z, .lineend
cp LF
jr z, .lineend
ld (de), a
inc de
jr .loop
.lineend:
; We've just finished reading a line, writing each char in the pad.
; Null terminate it.
xor a
ld (de), a
; Ok, line ready
push hl ; --> lvl 1. current file position
ld hl, SCRATCHPAD
call parseDecimalC
jr nz, .notANumber
call rdSep
call bufAdd
pop hl ; <-- lvl 1
ret nz
ld de, SCRATCHPAD
jr .loop
.notANumber:
pop hl ; <-- lvl 1
ld de, SCRATCHPAD
jr .loop
.loopend:
cp a
ret
basFOPEN:
call rdExpr ; file handle index
ret nz
push ix \ pop de
ld a, e
call fsHandle
; DE now points to file handle
call rdSep
; HL now holds the string we look for
call fsFindFN
ret nz ; not found
; Found!
; FS_PTR points to the file we want to open
push de \ pop ix ; IX now points to the file handle.
jp fsOpen
; Takes one byte block number to allocate as well we one string arg filename
; and allocates a new file in the current fs.
basFNEW:
call rdExpr ; file block count
ret nz
call rdSep ; HL now points to filename
push ix \ pop de
ld a, e
jp fsAlloc
; Deletes filename with specified name
basFDEL:
call fsFindFN
ret nz
; Found! delete
jp fsDel
basPgmHook:
; Cmd to find is in (DE)
ex de, hl
; (HL) is suitable for a direct fsFindFN call
call fsFindFN
ret nz
; We have a file! Let's load it in memory
ld ix, BFS_FILE_HDL
call fsOpen
ld hl, 0 ; addr that we read in file handle
ld de, USER_CODE ; addr in mem we write to
.loop:
call fsGetB ; we use Z at end of loop
ld (de), a ; Z preserved
inc hl ; Z preserved in 16-bit
inc de ; Z preserved in 16-bit
jr z, .loop
; Ready to jump. Return .call in IX and basCallCmd will take care
; of setting (HL) to the arg string. .call then takes care of wrapping
; the USER_CODE call.
ld ix, .call
cp a ; ensure Z
ret
.call:
ld iy, USER_CODE
call callIY
call basR2Var
or a ; Z set only if A is zero
ret
basFSCmds:
.db "fls", 0
.dw basFLS
.db "ldbas", 0
.dw basLDBAS
.db "fopen", 0
.dw basFOPEN
.db "fnew", 0
.dw basFNEW
.db "fdel", 0
.dw basFDEL
.db "fson", 0
.dw fsOn
.db 0xff ; end of table