Previous refacoring broke all seek/tell within fs. fs handles now lost the responsibility to keep track of current position. It's blkdev's job.pull/10/head
@@ -31,11 +31,10 @@ | |||
; parseHex | |||
; parseHexPair | |||
; blkSel | |||
; blkSet | |||
; fsFindFN | |||
; fsOpen | |||
; fsGetC | |||
; fsSeek | |||
; fsTell | |||
; cpHLDE | |||
; parseArgs | |||
; _blkGetC | |||
@@ -46,8 +46,10 @@ | |||
.equ IO_SAVED_POS IO_OUT_BLK+BLOCKDEV_SIZE | |||
; File handle for included source | |||
.equ IO_INCLUDE_HDL IO_SAVED_POS+2 | |||
; blkdev for include file | |||
.equ IO_INCLUDE_BLK IO_INCLUDE_HDL+FS_HANDLE_SIZE | |||
; see ioPutBack below | |||
.equ IO_PUTBACK_BUF IO_INCLUDE_HDL+FS_HANDLE_SIZE | |||
.equ IO_PUTBACK_BUF IO_INCLUDE_BLK+BLOCKDEV_SIZE | |||
.equ IO_IN_INCLUDE IO_PUTBACK_BUF+1 | |||
.equ IO_PC IO_IN_INCLUDE+1 | |||
; Current lineno in top-level file | |||
@@ -64,6 +66,9 @@ ioInit: | |||
xor a | |||
ld (IO_PUTBACK_BUF), a | |||
ld (IO_IN_INCLUDE), a | |||
ld de, IO_INCLUDE_BLK | |||
ld hl, _ioIncBlk | |||
call blkSet | |||
jp ioResetCounters | |||
ioGetC: | |||
@@ -73,8 +78,8 @@ ioGetC: | |||
call ioInInclude | |||
jr z, .normalmode | |||
; We're in "include mode", read from FS | |||
ld ix, IO_INCLUDE_HDL | |||
call fsGetC | |||
ld ix, IO_INCLUDE_BLK | |||
call _blkGetC | |||
cp 0x0a ; newline | |||
jr nz, .notNewline | |||
; We have newline. Increase lineno and return (the rest of the | |||
@@ -182,8 +187,8 @@ _ioSeek: | |||
jp _blkSeek | |||
.include: | |||
; We're in "include mode", seek in FS | |||
ld ix, IO_INCLUDE_HDL | |||
jp fsSeek ; returns | |||
ld ix, IO_INCLUDE_BLK | |||
jp _blkSeek ; returns | |||
_ioTell: | |||
call ioInInclude | |||
@@ -193,8 +198,8 @@ _ioTell: | |||
jp _blkTell | |||
.include: | |||
; We're in "include mode", tell from FS | |||
ld ix, IO_INCLUDE_HDL | |||
jp fsTell ; returns | |||
ld ix, IO_INCLUDE_BLK | |||
jp _blkTell ; returns | |||
; Sets Z according to whether we're inside an include | |||
ioInInclude: | |||
@@ -213,6 +218,9 @@ ioOpenInclude: | |||
ld (IO_IN_INCLUDE), a | |||
ld hl, 0 | |||
ld (IO_INC_LINENO), hl | |||
xor a | |||
ld ix, IO_INCLUDE_BLK | |||
call _blkSeek | |||
cp a ; ensure Z | |||
ret | |||
@@ -229,3 +237,10 @@ ioLineNo: | |||
pop af | |||
ret | |||
_ioIncGetC: | |||
ld ix, IO_INCLUDE_HDL | |||
jp fsGetC | |||
_ioIncBlk: | |||
.dw _ioIncGetC, unsetZ | |||
@@ -20,6 +20,7 @@ is configured to start at `0xe00` | |||
> fopn 0 hello.asm ; open file in handle 0 | |||
> zasm 1 3 ; assemble opened file and spit result in mmap | |||
> bsel 3 ; select mmap | |||
> mptr e000 ; set memptr to mmap's beginning | |||
> peek 5 | |||
210890CD3C ; looking good | |||
> mptr 4200 ; hello.asm is configured to run from 0x4200 | |||
@@ -58,7 +58,7 @@ blkSel: | |||
ld hl, blkDevTbl | |||
or a ; cp 0 | |||
jr z, .afterloop ; index is zero? don't loop | |||
jr z, .end ; index is zero? don't loop | |||
push bc ; <| | |||
ld b, a ; | | |||
.loop: ; | | |||
@@ -66,7 +66,19 @@ blkSel: | |||
call addHL ; | | |||
djnz .loop ; | | |||
pop bc ; <| | |||
.afterloop: | |||
.end: | |||
call blkSet | |||
pop hl | |||
pop de | |||
pop af | |||
ret | |||
; Setup blkdev handle in (DE) using routines at (HL). | |||
blkSet: | |||
push af | |||
push de | |||
push hl | |||
; Write GETC | |||
push hl ; <| | |||
call intoHL ; | | |||
@@ -86,9 +86,8 @@ | |||
.equ FS_META_FNAME_OFFSET 6 | |||
; Size in bytes of a FS handle: | |||
; * 4 bytes for starting offset of the FS block | |||
; * 2 bytes for current position relative to block's position | |||
; * 2 bytes for file size | |||
.equ FS_HANDLE_SIZE 8 | |||
.equ FS_HANDLE_SIZE 6 | |||
.equ FS_ERR_NO_FS 0x5 | |||
.equ FS_ERR_NOT_FOUND 0x6 | |||
@@ -390,76 +389,63 @@ fsOpen: | |||
ld (ix+2), a | |||
ld a, (FS_BLK+7) | |||
ld (ix+3), a | |||
; Current pos | |||
ld hl, FS_METASIZE | |||
ld (ix+4), l | |||
ld (ix+5), h | |||
; file size | |||
ld hl, (FS_META+FS_META_FSIZE_OFFSET) | |||
ld (ix+6), l | |||
ld (ix+7), h | |||
ld (ix+4), l | |||
ld (ix+5), h | |||
pop af | |||
pop hl | |||
ret | |||
; Place FS blockdev at proper position for file handle in (IX). | |||
; Place FS blockdev at proper position for file handle in (IX) at position HL. | |||
fsPlaceH: | |||
push af | |||
push bc | |||
push hl | |||
push de | |||
push hl | |||
; Move fsdev to beginning of block | |||
ld e, (ix) | |||
ld d, (ix+1) | |||
ld l, (ix+2) | |||
ld h, (ix+3) | |||
ld c, (ix+4) | |||
ld b, (ix+5) | |||
add hl, bc | |||
jr nc, .nocarry | |||
inc de | |||
.nocarry: | |||
ld a, BLOCKDEV_SEEK_ABSOLUTE | |||
call fsblkSeek | |||
pop de | |||
; skip metadata | |||
ld a, BLOCKDEV_SEEK_FORWARD | |||
ld hl, FS_METASIZE | |||
call fsblkSeek | |||
pop hl | |||
pop bc | |||
pop af | |||
ret | |||
pop de | |||
; Advance file handle in (IX) by one byte | |||
fsAdvanceH: | |||
push af | |||
inc (ix+4) | |||
jr nz, .end | |||
inc (ix+5) | |||
.end: | |||
; go to specified pos | |||
ld a, BLOCKDEV_SEEK_FORWARD | |||
call fsblkSeek | |||
pop af | |||
ret | |||
; Sets Z according to whether file handle at (IX) is within bounds, that is, if | |||
; current position is smaller than file size. | |||
fsHandleWithinBounds: | |||
push hl | |||
; Advance file handle in (IX) by one byte | |||
; Sets Z according to whether HL is within bounds for file handle at (IX), that | |||
; is, if it is smaller than file size. | |||
fsWithinBounds: | |||
push de | |||
; current pos in HL, adjusted to remove FS_METASIZE | |||
call fsTell | |||
; file size | |||
ld e, (ix+6) | |||
ld d, (ix+7) | |||
ld e, (ix+4) | |||
ld d, (ix+5) | |||
call cpHLDE | |||
pop de | |||
pop hl | |||
jr nc, .outOfBounds ; HL >= DE | |||
cp a ; ensure Z | |||
ret | |||
.outOfBounds: | |||
jp unsetZ ; returns | |||
; Read a byte in handle at (IX), put it into A and advance the handle's | |||
; position. | |||
; Read a byte in handle at (IX) at position HL and put it into A. | |||
; Z is set on success, unset if handle is at the end of the file. | |||
fsGetC: | |||
call fsHandleWithinBounds | |||
ld a, h | |||
ld a, l | |||
call fsWithinBounds | |||
jr z, .proceed | |||
; We want to unset Z, but also return 0 to ensure that a GetC that | |||
; doesn't check Z doesn't end up with false data. | |||
@@ -467,35 +453,14 @@ fsGetC: | |||
jp unsetZ ; returns | |||
.proceed: | |||
call fsPlaceH | |||
call fsblkGetC | |||
ret nz ; error, don't advance | |||
; increase current pos | |||
jp fsAdvanceH ; returns | |||
jp fsblkGetC ; returns | |||
; Write byte A in handle (IX) and advance the handle's position. | |||
; Z is set on success, unset if handle is at the end of the file. | |||
; TODO: detect end of block alloc | |||
fsPutC: | |||
call fsPlaceH | |||
call fsblkPutC | |||
jp fsAdvanceH ; returns | |||
; Sets position of handle (IX) to HL. This position does *not* include metadata. | |||
; It is an offset that starts at actual data. | |||
; Sets Z if offset is within bounds, unsets Z if it isn't. | |||
fsSeek: | |||
ld a, FS_METASIZE | |||
call addHL | |||
ld (ix+4), l | |||
ld (ix+5), h | |||
ret | |||
; Returns current position of file handle at (IX) in HL. | |||
fsTell: | |||
ld l, (ix+4) | |||
ld h, (ix+5) | |||
ld a, FS_METASIZE | |||
jp subHL ; returns | |||
jp fsblkPutC ; returns | |||
; Mount the fs subsystem upon the currently selected blockdev at current offset. | |||
; Verify is block is valid and error out if its not, mounting nothing. | |||
@@ -120,6 +120,8 @@ static void io_write(int unused, uint16_t addr, uint8_t val) | |||
fsdev_ptr |= val; | |||
fsdev_addr_lvl = 0; | |||
} | |||
} else { | |||
fprintf(stderr, "Out of bounds I/O write: %d / %d (0x%x)\n", addr, val, val); | |||
} | |||
} | |||
@@ -23,11 +23,10 @@ | |||
jp parseHex | |||
jp parseHexPair | |||
jp blkSel | |||
jp blkSet | |||
jp fsFindFN | |||
jp fsOpen | |||
jp fsGetC | |||
jp fsSeek | |||
jp fsTell | |||
jp cpHLDE | |||
jp parseArgs | |||
jp printstr | |||
@@ -16,15 +16,14 @@ | |||
.equ parseHex 0x1e | |||
.equ parseHexPair 0x21 | |||
.equ blkSel 0x24 | |||
.equ fsFindFN 0x27 | |||
.equ fsOpen 0x2a | |||
.equ fsGetC 0x2d | |||
.equ fsSeek 0x30 | |||
.equ fsTell 0x33 | |||
.equ cpHLDE 0x36 | |||
.equ parseArgs 0x39 | |||
.equ printstr 0x3c | |||
.equ _blkGetC 0x3f | |||
.equ _blkPutC 0x42 | |||
.equ _blkSeek 0x45 | |||
.equ _blkTell 0x48 | |||
.equ blkSet 0x27 | |||
.equ fsFindFN 0x2a | |||
.equ fsOpen 0x2d | |||
.equ fsGetC 0x30 | |||
.equ cpHLDE 0x33 | |||
.equ parseArgs 0x36 | |||
.equ printstr 0x39 | |||
.equ _blkGetC 0x3c | |||
.equ _blkPutC 0x3f | |||
.equ _blkSeek 0x42 | |||
.equ _blkTell 0x45 |
@@ -21,11 +21,10 @@ jp findchar | |||
jp parseHex | |||
jp parseHexPair | |||
jp blkSel | |||
jp blkSet | |||
jp fsFindFN | |||
jp fsOpen | |||
jp fsGetC | |||
jp fsSeek | |||
jp fsTell | |||
jp cpHLDE | |||
jp parseArgs | |||
jp _blkGetC | |||
@@ -16,14 +16,13 @@ | |||
.equ parseHex 0x1e | |||
.equ parseHexPair 0x21 | |||
.equ blkSel 0x24 | |||
.equ fsFindFN 0x27 | |||
.equ fsOpen 0x2a | |||
.equ fsGetC 0x2d | |||
.equ fsSeek 0x30 | |||
.equ fsTell 0x33 | |||
.equ cpHLDE 0x36 | |||
.equ parseArgs 0x39 | |||
.equ _blkGetC 0x3c | |||
.equ _blkPutC 0x3f | |||
.equ _blkSeek 0x42 | |||
.equ _blkTell 0x45 | |||
.equ blkSet 0x27 | |||
.equ fsFindFN 0x2a | |||
.equ fsOpen 0x2d | |||
.equ fsGetC 0x30 | |||
.equ cpHLDE 0x33 | |||
.equ parseArgs 0x36 | |||
.equ _blkGetC 0x39 | |||
.equ _blkPutC 0x3c | |||
.equ _blkSeek 0x3f | |||
.equ _blkTell 0x42 |
@@ -16,17 +16,16 @@ | |||
.equ parseHex 0x1e | |||
.equ parseHexPair 0x21 | |||
.equ blkSel 0x24 | |||
.equ fsFindFN 0x27 | |||
.equ fsOpen 0x2a | |||
.equ fsGetC 0x2d | |||
.equ fsSeek 0x30 | |||
.equ fsTell 0x33 | |||
.equ cpHLDE 0x36 | |||
.equ parseArgs 0x39 | |||
.equ _blkGetC 0x3c | |||
.equ _blkPutC 0x3f | |||
.equ _blkSeek 0x42 | |||
.equ _blkTell 0x45 | |||
.equ blkSet 0x27 | |||
.equ fsFindFN 0x2a | |||
.equ fsOpen 0x2d | |||
.equ fsGetC 0x30 | |||
.equ cpHLDE 0x33 | |||
.equ parseArgs 0x36 | |||
.equ _blkGetC 0x39 | |||
.equ _blkPutC 0x3c | |||
.equ _blkSeek 0x3f | |||
.equ _blkTell 0x42 | |||
#include "err.h" | |||
#include "zasm/const.asm" | |||