fs: check for file size bounds in GetC

This commit is contained in:
Virgil Dupras 2019-05-31 11:12:29 -04:00
parent a641a94853
commit 83771b538f
8 changed files with 107 additions and 32 deletions

View File

@ -36,6 +36,7 @@
; fsGetC
; fsSeek
; fsTell
; cpHLDE
; FS_HANDLE_SIZE
; *** Variables ***

View File

@ -12,16 +12,6 @@ callHL:
jp (hl)
ret
; Compare HL with DE and sets Z and C in the same way as a regular cp X where
; HL is A and DE is X.
cpHLDE:
ld a, h
cp d
ret nz ; if not equal, flags are correct
ld a, l
cp e
ret ; flags are correct
; HL - DE -> HL
subDEFromHL:
push af

View File

@ -22,6 +22,7 @@ addDE:
.end:
ld e, a
pop af
noop: ; piggy backing on the first "ret" we have
ret
; copy (DE) into DE, little endian style (addresses in z80 are always have
@ -71,6 +72,16 @@ subHL:
pop af
ret
; Compare HL with DE and sets Z and C in the same way as a regular cp X where
; HL is A and DE is X.
cpHLDE:
ld a, h
cp d
ret nz ; if not equal, flags are correct
ld a, l
cp e
ret ; flags are correct
; Write the contents of HL in (DE)
writeHLinDE:
push af
@ -84,14 +95,12 @@ writeHLinDE:
ret
; jump to the location pointed to by IX. This allows us to call IX instead of
; just jumping it. We use IX because we never use this for arguments.
; just jumping it. We use IX because we seldom use this for arguments.
callIX:
jp (ix)
ret
callIY:
jp (iy)
ret
; Ensures that Z is unset (more complicated than it sounds...)
unsetZ:

View File

@ -87,7 +87,8 @@
; 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
.equ FS_HANDLE_SIZE 6
; * 2 bytes for file size
.equ FS_HANDLE_SIZE 8
.equ FS_ERR_NO_FS 0x5
.equ FS_ERR_NOT_FOUND 0x6
@ -387,6 +388,11 @@ fsOpen:
; Current pos
ld hl, FS_METASIZE
call writeHLinDE
inc de
inc de
; file size
ld hl, (FS_META+FS_META_FSIZE_OFFSET)
call writeHLinDE
pop af
pop de
pop hl
@ -429,11 +435,37 @@ fsAdvanceH:
pop af
ret
; Sets Z according to whether file handle at (DE) is within bounds, that is, if
; current position is smaller than file size.
fsHandleWithinBounds:
push hl
; current pos in HL, adjusted to remove FS_METASIZE
call fsTell
push de
push de \ pop ix
; file size
ld e, (ix+6)
ld d, (ix+7)
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 (DE), put it into A 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 file
fsGetC:
call fsHandleWithinBounds
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.
xor a
jp unsetZ ; returns
.proceed:
push ix
call fsPlaceH
push ix ; Save handle in IX for fsAdvanceH
@ -514,3 +546,22 @@ fsOn:
pop de
pop hl
ret
; Sets Z according to whether we have a filesystem mounted.
fsIsOn:
; check whether (FS_GETC) is zero
push hl
push de
ld hl, (FS_GETC)
ld de, 0
call cpHLDE
jr nz, .mounted
; if equal, it means our FS is not mounted
call unsetZ
jr .end
.mounted:
cp a ; ensure Z
.end:
pop de
pop hl
ret

View File

@ -20,3 +20,4 @@
.equ fsGetC 0x2d
.equ fsSeek 0x30
.equ fsTell 0x33
.equ cpHLDE 0x36

View File

@ -26,6 +26,7 @@ jp fsOpen
jp fsGetC
jp fsSeek
jp fsTell
jp cpHLDE
#include "core.asm"
#include "parse.asm"

View File

@ -8,6 +8,7 @@ test:
ld hl, 0xffff
ld sp, hl
; *** subHL ***
ld hl, 0x123
ld a, 0x25
call subHL
@ -41,6 +42,26 @@ test:
jp nz, fail
call nexttest
; *** cpHLDE ***
ld hl, 0x42
ld de, 0x42
call cpHLDE
jp nz, fail
jp c, fail
call nexttest
ld de, 0x4242
call cpHLDE
jp z, fail
jp nc, fail
call nexttest
ld hl, 0x4243
call cpHLDE
jp z, fail
jp c, fail
call nexttest
; success
xor a
halt

View File

@ -20,6 +20,7 @@
.equ fsGetC 0x2d
.equ fsSeek 0x30
.equ fsTell 0x33
.equ cpHLDE 0x36
#include "zasm/const.asm"
#include "zasm/util.asm"