parts/z80/fs: add "fopn" command

This commit is contained in:
Virgil Dupras 2019-05-12 15:38:58 -04:00
parent 9b4b907236
commit 4f44d3de63
4 changed files with 120 additions and 23 deletions

View File

@ -33,6 +33,7 @@ table describes those codes:
| `02` | Badly formatted arguments | | `02` | Badly formatted arguments |
| `03` | Out of bounds | | `03` | Out of bounds |
| `04` | Unsupported command | | `04` | Unsupported command |
| `05` | I/O error |
## mptr ## mptr

View File

@ -292,6 +292,25 @@ fsAlloc:
pop bc pop bc
ret ret
; Place FS_PTR to the filename with the name in (HL).
; Sets Z on success, unset when not found.
fsFindFN:
push de
call fsBegin
jr nz, .end ; nothing to find, Z is unset
ld a, FS_MAX_NAME_SIZE
.loop:
ld de, FS_META+FS_META_FNAME_OFFSET
call strncmp
jr z, .end ; Z is set
call fsNext
jr z, .loop
; End of the chain, not found
call unsetZ
.end:
pop de
ret
; *** Metadata *** ; *** Metadata ***
; Sets Z according to whether the current block in FS_META is valid. ; Sets Z according to whether the current block in FS_META is valid.
@ -378,6 +397,7 @@ fsOpen:
pop hl pop hl
ret ret
; Place FS blockdev at proper position for file handle in (DE).
fsPlaceH: fsPlaceH:
push af push af
push hl push hl
@ -393,23 +413,31 @@ fsPlaceH:
pop af pop af
ret ret
; Advance file handle in (IX) by one byte
fsAdvanceH: fsAdvanceH:
push af
inc (ix) inc (ix)
ld a, (ix) ld a, (ix)
ret nc ; no carry jr nc, .end
inc (ix+1) inc (ix+1)
.end:
pop af
ret ret
; Read a byte in handle at (DE), put it into A and advance the handle's ; Read a byte in handle at (DE), put it into A and advance the handle's
; position. ; position.
; Z is set on success, unset if handle is at the end of the file. ; Z is set on success, unset if handle is at the end of the file.
fsGetC: fsGetC:
call fsPlaceH
push ix push ix
call fsPlaceH
push ix ; Save handle in IX for fsAdvanceH
call fsblkGetC call fsblkGetC
; increase current pos ; increase current pos
pop ix ; recall pop ix ; recall handle in IX
jr nz, .end ; error, don't advance
call fsAdvanceH call fsAdvanceH
.end:
pop ix
ret ret
; Write byte A in handle (DE) and advance the handle's position. ; Write byte A in handle (DE) and advance the handle's position.
@ -494,7 +522,7 @@ flsCmd:
call printcrlf call printcrlf
.skip: .skip:
call fsNext call fsNext
jr z, .loop ; Z set? fsNext was successfull jr z, .loop ; Z set? fsNext was successful
xor a xor a
jr .end jr .end
.error: .error:
@ -520,20 +548,10 @@ fdelCmd:
.db "fdel", 0b1001, 0b001, 0 .db "fdel", 0b1001, 0b001, 0
push hl push hl
push de push de
ex hl, de call intoHL ; HL now holds the string we look for
call intoDE ; DE now holds the string we look for call fsFindFN
call fsBegin
jr nz, .notfound jr nz, .notfound
ld a, FS_MAX_NAME_SIZE ; Found! delete
.loop:
ld hl, FS_META+FS_META_FNAME_OFFSET
call strncmp
jr z, .found
call fsNext
jr z, .loop
; End of chain, not found
jr .notfound
.found:
xor a xor a
; Set filename to zero to flag it as deleted ; Set filename to zero to flag it as deleted
ld (FS_META+FS_META_FNAME_OFFSET), a ld (FS_META+FS_META_FNAME_OFFSET), a
@ -546,3 +564,30 @@ fdelCmd:
pop de pop de
pop hl pop hl
ret ret
; Opens specified filename in specified file handle.
; First argument is file handle, second one is file name.
; Example: fopn 0 foo.txt
fopnCmd:
.db "fopn", 0b001, 0b1001, 0b001
push hl
push de
ld a, (hl) ; file handle index
ld de, FS_HANDLES
call addDE ; DE now stores pointer to file handle
inc hl
call intoHL ; HL now holds the string we look for
call fsFindFN
jr nz, .notfound
; Found!
; FS_PTR points to the file we want to open
ex hl, de ; HL now points to the file handle.
call fsOpen
jr .end
.notfound:
ld a, FS_ERR_NOT_FOUND
.end:
pop de
pop hl
ret

View File

@ -38,6 +38,9 @@ SHELL_ERR_UNKNOWN_CMD .equ 0x01
; Arguments for the command weren't properly formatted ; Arguments for the command weren't properly formatted
SHELL_ERR_BAD_ARGS .equ 0x02 SHELL_ERR_BAD_ARGS .equ 0x02
; IO routines (GetC, PutC) returned an error in a load/save command
SHELL_ERR_IO_ERROR .equ 0x05
; Size of the shell command buffer. If a typed command reaches this size, the ; Size of the shell command buffer. If a typed command reaches this size, the
; command is flushed immediately (same as pressing return). ; command is flushed immediately (same as pressing return).
SHELL_BUFSIZE .equ 0x20 SHELL_BUFSIZE .equ 0x20
@ -409,14 +412,18 @@ shellLoad:
ld b, a ld b, a
ld hl, (SHELL_MEM_PTR) ld hl, (SHELL_MEM_PTR)
.loop: SHELL_IO_GETC .loop: SHELL_IO_GETC
jr nz, .ioError
ld (hl), a ld (hl), a
inc hl inc hl
djnz .loop djnz .loop
; success
xor a
jr .end
.ioError:
ld a, SHELL_ERR_IO_ERROR
.end: .end:
pop hl pop hl
pop bc pop bc
xor a
ret ret
; Load the specified number of bytes (max 0xff) from the current memory pointer ; Load the specified number of bytes (max 0xff) from the current memory pointer

View File

@ -15,11 +15,13 @@ STDIO_RAMSTART .equ RAMEND
#include "stdio.asm" #include "stdio.asm"
BLOCKDEV_RAMSTART .equ STDIO_RAMEND BLOCKDEV_RAMSTART .equ STDIO_RAMEND
BLOCKDEV_COUNT .equ 2 BLOCKDEV_COUNT .equ 4
#include "blockdev.asm" #include "blockdev.asm"
; List of devices ; List of devices
.dw emulGetC, emulPutC, 0, 0 .dw emulGetC, emulPutC, 0, 0
.dw fsdevGetC, fsdevPutC, fsdevSeek, fsdevTell .dw fsdevGetC, fsdevPutC, fsdevSeek, fsdevTell
.dw stdoutGetC, stdoutPutC, stdoutSeek, stdoutTell
.dw stdinGetC, stdinPutC, stdinSeek, stdinTell
#include "blockdev_cmds.asm" #include "blockdev_cmds.asm"
@ -28,11 +30,11 @@ BLOCKDEV_COUNT .equ 2
#include "fs.asm" #include "fs.asm"
SHELL_RAMSTART .equ FS_RAMEND SHELL_RAMSTART .equ FS_RAMEND
.define SHELL_IO_GETC call blkGetCW .define SHELL_IO_GETC call blkGetC
.define SHELL_IO_PUTC call blkPutC .define SHELL_IO_PUTC call blkPutC
SHELL_EXTRA_CMD_COUNT .equ 6 SHELL_EXTRA_CMD_COUNT .equ 7
#include "shell.asm" #include "shell.asm"
.dw blkBselCmd, blkSeekCmd, fsOnCmd, flsCmd, fnewCmd, fdelCmd .dw blkBselCmd, blkSeekCmd, fsOnCmd, flsCmd, fnewCmd, fdelCmd, fopnCmd
init: init:
di di
@ -62,6 +64,7 @@ emulPutC:
fsdevGetC: fsdevGetC:
in a, (FS_DATA_PORT) in a, (FS_DATA_PORT)
cp a ; ensure Z
ret ret
fsdevPutC: fsdevPutC:
@ -69,15 +72,56 @@ fsdevPutC:
ret ret
fsdevSeek: fsdevSeek:
push af
ld a, l ld a, l
out (FS_SEEKL_PORT), a out (FS_SEEKL_PORT), a
ld a, h ld a, h
out (FS_SEEKH_PORT), a out (FS_SEEKH_PORT), a
pop af
ret ret
fsdevTell: fsdevTell:
push af
in a, (FS_SEEKL_PORT) in a, (FS_SEEKL_PORT)
ld l, a ld l, a
in a, (FS_SEEKH_PORT) in a, (FS_SEEKH_PORT)
ld h, a ld h, a
pop af
ret ret
.equ STDOUT_HANDLE FS_HANDLES
stdoutGetC:
ld de, STDOUT_HANDLE
jp fsGetC
stdoutPutC:
ld de, STDOUT_HANDLE
jp fsPutC
stdoutSeek:
ld de, STDOUT_HANDLE
jp fsSeek
stdoutTell:
ld de, STDOUT_HANDLE
jp fsTell
.equ STDIN_HANDLE FS_HANDLES+FS_HANDLE_SIZE
stdinGetC:
ld de, STDIN_HANDLE
jp fsGetC
stdinPutC:
ld de, STDIN_HANDLE
jp fsPutC
stdinSeek:
ld de, STDIN_HANDLE
jp fsSeek
stdinTell:
ld de, STDIN_HANDLE
jp fsTell