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 ; fsGetC
; fsSeek ; fsSeek
; fsTell ; fsTell
; cpHLDE
; FS_HANDLE_SIZE ; FS_HANDLE_SIZE
; *** Variables *** ; *** Variables ***

View File

@ -12,16 +12,6 @@ callHL:
jp (hl) jp (hl)
ret 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 ; HL - DE -> HL
subDEFromHL: subDEFromHL:
push af push af

View File

@ -22,6 +22,7 @@ addDE:
.end: .end:
ld e, a ld e, a
pop af pop af
noop: ; piggy backing on the first "ret" we have
ret ret
; copy (DE) into DE, little endian style (addresses in z80 are always have ; copy (DE) into DE, little endian style (addresses in z80 are always have
@ -71,6 +72,16 @@ subHL:
pop af pop af
ret 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) ; Write the contents of HL in (DE)
writeHLinDE: writeHLinDE:
push af push af
@ -84,14 +95,12 @@ writeHLinDE:
ret ret
; jump to the location pointed to by IX. This allows us to call IX instead of ; 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: callIX:
jp (ix) jp (ix)
ret
callIY: callIY:
jp (iy) jp (iy)
ret
; Ensures that Z is unset (more complicated than it sounds...) ; Ensures that Z is unset (more complicated than it sounds...)
unsetZ: unsetZ:

View File

@ -87,7 +87,8 @@
; Size in bytes of a FS handle: ; Size in bytes of a FS handle:
; * 4 bytes for starting offset of the FS block ; * 4 bytes for starting offset of the FS block
; * 2 bytes for current position relative to block's position ; * 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_NO_FS 0x5
.equ FS_ERR_NOT_FOUND 0x6 .equ FS_ERR_NOT_FOUND 0x6
@ -387,6 +388,11 @@ fsOpen:
; Current pos ; Current pos
ld hl, FS_METASIZE ld hl, FS_METASIZE
call writeHLinDE call writeHLinDE
inc de
inc de
; file size
ld hl, (FS_META+FS_META_FSIZE_OFFSET)
call writeHLinDE
pop af pop af
pop de pop de
pop hl pop hl
@ -429,11 +435,37 @@ fsAdvanceH:
pop af pop af
ret 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 ; 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.
; TODO: detect end of file
fsGetC: 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 push ix
call fsPlaceH call fsPlaceH
push ix ; Save handle in IX for fsAdvanceH push ix ; Save handle in IX for fsAdvanceH
@ -514,3 +546,22 @@ fsOn:
pop de pop de
pop hl pop hl
ret 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 fsGetC 0x2d
.equ fsSeek 0x30 .equ fsSeek 0x30
.equ fsTell 0x33 .equ fsTell 0x33
.equ cpHLDE 0x36

View File

@ -9,23 +9,24 @@
jp init ; 3 bytes jp init ; 3 bytes
; *** JUMP TABLE *** ; *** JUMP TABLE ***
jp strncmp jp strncmp
jp addDE jp addDE
jp addHL jp addHL
jp upcase jp upcase
jp unsetZ jp unsetZ
jp intoDE jp intoDE
jp intoHL jp intoHL
jp writeHLinDE jp writeHLinDE
jp findchar jp findchar
jp parseHex jp parseHex
jp parseHexPair jp parseHexPair
jp blkSel jp blkSel
jp fsFindFN jp fsFindFN
jp fsOpen jp fsOpen
jp fsGetC jp fsGetC
jp fsSeek jp fsSeek
jp fsTell jp fsTell
jp cpHLDE
#include "core.asm" #include "core.asm"
#include "parse.asm" #include "parse.asm"

View File

@ -8,6 +8,7 @@ test:
ld hl, 0xffff ld hl, 0xffff
ld sp, hl ld sp, hl
; *** subHL ***
ld hl, 0x123 ld hl, 0x123
ld a, 0x25 ld a, 0x25
call subHL call subHL
@ -41,6 +42,26 @@ test:
jp nz, fail jp nz, fail
call nexttest 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 ; success
xor a xor a
halt halt

View File

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