; 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