1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-23 23:38:06 +11:00

fs: add private "blk" routines

This way, we can interact with the mounted FS even when we change the
selected blkdev.
This commit is contained in:
Virgil Dupras 2019-04-23 15:50:26 -04:00
parent 3ba0a707e7
commit f00334ec89
3 changed files with 76 additions and 21 deletions

View File

@ -108,9 +108,11 @@ blkGetCW:
; Reads B chars from blkGetC and copy them in (HL). ; Reads B chars from blkGetC and copy them in (HL).
; Sets Z if successful, unset Z if there was an error. ; Sets Z if successful, unset Z if there was an error.
blkRead: blkRead:
ld ix, (BLOCKDEV_GETC)
_blkRead:
push hl push hl
.loop: .loop:
call blkGetC call _blkCall
jr nz, .end ; Z already unset jr nz, .end ; Z already unset
ld (hl), a ld (hl), a
inc hl inc hl
@ -129,10 +131,12 @@ blkPutC:
; Writes B chars to blkPutC from (HL). ; Writes B chars to blkPutC from (HL).
; Sets Z if successful, unset Z if there was an error. ; Sets Z if successful, unset Z if there was an error.
blkWrite: blkWrite:
ld ix, (BLOCKDEV_PUTC)
_blkWrite:
push hl push hl
.loop: .loop:
ld a, (hl) ld a, (hl)
call blkPutC call _blkCall
jr nz, .end ; Z already unset jr nz, .end ; Z already unset
inc hl inc hl
djnz .loop djnz .loop
@ -149,6 +153,9 @@ blkWrite:
; 4 : Move to the beginning ; 4 : Move to the beginning
; Set position of selected device to the value specified in HL ; Set position of selected device to the value specified in HL
blkSeek: blkSeek:
ld ix, (BLOCKDEV_SEEK)
ld iy, (BLOCKDEV_TELL)
_blkSeek:
push de push de
cp BLOCKDEV_SEEK_FORWARD cp BLOCKDEV_SEEK_FORWARD
jr z, .forward jr z, .forward
@ -162,7 +169,10 @@ blkSeek:
jr .seek ; for absolute mode, HL is already correct jr .seek ; for absolute mode, HL is already correct
.forward: .forward:
ex hl, de ; DE has our offset ex hl, de ; DE has our offset
call blkTell ; HL has our curpos ; We want to be able to plug our own TELL function, which is why we
; don't call blkTell directly here.
; Calling TELL
call callIY ; HL has our curpos
add hl, de add hl, de
jr nc, .seek ; no carry? alright! jr nc, .seek ; no carry? alright!
; we have carry? out of bounds, set to maximum ; we have carry? out of bounds, set to maximum
@ -176,7 +186,6 @@ blkSeek:
ld hl, 0xffff ld hl, 0xffff
.seek: .seek:
pop de pop de
ld ix, (BLOCKDEV_SEEK)
jr _blkCall jr _blkCall
; Returns the current position of the selected device in HL. ; Returns the current position of the selected device in HL.

View File

@ -71,6 +71,10 @@ callIX:
jp (ix) jp (ix)
ret ret
callIY:
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:
push bc push bc

View File

@ -95,13 +95,16 @@ FS_ERR_NO_FS .equ 0x5
FS_ERR_NOT_FOUND .equ 0x6 FS_ERR_NOT_FOUND .equ 0x6
; *** VARIABLES *** ; *** VARIABLES ***
; A copy of BLOCKDEV_SEL when the FS was mounted. 0 if no FS is mounted. ; A copy of BLOCKDEV routines when the FS was mounted. 0 if no FS is mounted.
FS_BLKSEL .equ FS_RAMSTART FS_GETC .equ FS_RAMSTART
FS_PUTC .equ FS_GETC+2
FS_SEEK .equ FS_PUTC+2
FS_TELL .equ FS_SEEK+2
; Offset at which our FS start on mounted device ; Offset at which our FS start on mounted device
FS_START .equ FS_BLKSEL+2 FS_START .equ FS_TELL+2
; Offset at which we are currently pointing to with regards to our routines ; Offset at which we are currently pointing to with regards to our routines
; below, which all assume this offset as a context. This offset is not relative ; below, which all assume this offset as a context. This offset is not relative
; to FS_START. It can be used directly with blkSeek. ; to FS_START. It can be used directly with fsblkSeek.
FS_PTR .equ FS_START+2 FS_PTR .equ FS_START+2
; This variable below contain the metadata of the last block FS_PTR was moved ; This variable below contain the metadata of the last block FS_PTR was moved
; to. We read this data in memory to avoid constant seek+read operations. ; to. We read this data in memory to avoid constant seek+read operations.
@ -117,8 +120,8 @@ P_FS_MAGIC:
fsInit: fsInit:
xor a xor a
ld hl, FS_BLKSEL ld hl, FS_GETC
ld b, FS_RAMEND-FS_BLKSEL ld b, FS_RAMEND-FS_GETC
call fill call fill
ret ret
@ -150,10 +153,10 @@ fsNext:
ld a, BLOCKDEV_SEEK_FORWARD ld a, BLOCKDEV_SEEK_FORWARD
ld hl, FS_BLOCKSIZE ld hl, FS_BLOCKSIZE
.loop: .loop:
call blkSeek call fsblkSeek
djnz .loop djnz .loop
; Good, were here. We're going to read meta from our current position. ; Good, were here. We're going to read meta from our current position.
call blkTell ; --> HL call fsblkTell ; --> HL
ld (FS_PTR), hl ld (FS_PTR), hl
call fsReadMeta call fsReadMeta
jr nz, .createChainEnd jr nz, .createChainEnd
@ -178,27 +181,27 @@ fsNext:
ret ret
; Reads metadata at current FS_PTR and place it in FS_META. ; Reads metadata at current FS_PTR and place it in FS_META.
; Returns Z according to whether the blkRead operation succeeded. ; Returns Z according to whether the fsblkRead operation succeeded.
fsReadMeta: fsReadMeta:
call fsPlace call fsPlace
push bc push bc
push hl push hl
ld b, 0x20 ld b, 0x20
ld hl, FS_META ld hl, FS_META
call blkRead ; Sets Z call fsblkRead ; Sets Z
pop hl pop hl
pop bc pop bc
ret ret
; Writes metadata in FS_META at current FS_PTR. ; Writes metadata in FS_META at current FS_PTR.
; Returns Z according to whether the blkWrite operation succeeded. ; Returns Z according to whether the fsblkWrite operation succeeded.
fsWriteMeta: fsWriteMeta:
call fsPlace call fsPlace
push bc push bc
push hl push hl
ld b, 0x20 ld b, 0x20
ld hl, FS_META ld hl, FS_META
call blkWrite ; Sets Z call fsblkWrite ; Sets Z
pop hl pop hl
pop bc pop bc
ret ret
@ -228,7 +231,7 @@ fsPlace:
push hl push hl
xor a xor a
ld hl, (FS_PTR) ld hl, (FS_PTR)
call blkSeek call fsblkSeek
pop hl pop hl
pop af pop af
ret ret
@ -279,7 +282,7 @@ fsAlloc:
ldir ldir
; Good, FS_META ready. Now, let's update FS_PTR because it hasn't been ; Good, FS_META ready. Now, let's update FS_PTR because it hasn't been
; changed yet. ; changed yet.
call blkTell call fsblkTell
ld (FS_PTR), hl ld (FS_PTR), hl
; Ok, now we can write our metadata ; Ok, now we can write our metadata
call fsWriteMeta call fsWriteMeta
@ -311,6 +314,28 @@ fsIsDeleted:
cp 0 ; Z flag is our answer cp 0 ; Z flag is our answer
ret ret
; *** blkdev methods ***
; When "mounting" a FS, we copy the current blkdev's routine privately so that
; we can still access the FS even if blkdev selection changes. These routines
; below mimic blkdev's methods, but for our private mount.
fsblkRead:
ld ix, (FS_GETC)
jp _blkRead
fsblkWrite:
ld ix, (FS_PUTC)
jp _blkWrite
fsblkSeek:
ld ix, (FS_SEEK)
ld iy, (FS_TELL)
jp _blkSeek
fsblkTell:
ld ix, (FS_TELL)
jp _blkCall
; *** Handling *** ; *** Handling ***
; Open file at current position into handle at (HL) ; Open file at current position into handle at (HL)
@ -341,23 +366,40 @@ fsSeek:
; *** SHELL COMMANDS *** ; *** SHELL COMMANDS ***
; Mount the fs subsystem upon the currently selected blockdev at current offset. ; 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. ; Verify is block is valid and error out if its not, mounting nothing.
; Upon mounting, copy currently selected device in FS_BLKSEL. ; Upon mounting, copy currently selected device in FS_GETC/PUTC/SEEK/TELL.
fsOnCmd: fsOnCmd:
.db "fson", 0, 0, 0 .db "fson", 0, 0, 0
push hl push hl
call blkTell push de
push bc
; We have to set blkdev routines early before knowing whether the
; mounting succeeds because methods like fsReadMeta uses fsblk* methods.
ld hl, BLOCKDEV_GETC
ld de, FS_GETC
ld bc, 8 ; we have 8 bytes to copy
ldir ; copy!
call fsblkTell
ld (FS_START), hl
ld (FS_PTR), hl ld (FS_PTR), hl
call fsReadMeta call fsReadMeta
jr nz, .error jr nz, .error
call fsIsValid call fsIsValid
jr nz, .error jr nz, .error
; success ; success
ld (FS_START), hl
xor a xor a
jr .end jr .end
.error: .error:
; couldn't mount. Let's reset our variables.
xor a
ld b, 10 ; blkdev routines + FS_START which is just
; after.
ld hl, FS_GETC
call fill
ld a, FS_ERR_NO_FS ld a, FS_ERR_NO_FS
.end: .end:
pop bc
pop de
pop hl pop hl
ret ret