diff --git a/apps/ed/README.md b/apps/ed/README.md index 6db9de6..19b7220 100644 --- a/apps/ed/README.md +++ b/apps/ed/README.md @@ -39,7 +39,8 @@ range is out of bounds. * `(addrs)d`: Delete lines specified in `addrs` range. * `(addr)a`: Appends a line after `addr`. * `(addr)i`: Insert a line before `addr`. -* `q`: quit `ed` +* `w`: write to file. For now, `q` is implied in `w`. +* `q`: quit `ed` without writing to file. ### Current line diff --git a/apps/ed/cmd.asm b/apps/ed/cmd.asm index 473d17c..cfa761f 100644 --- a/apps/ed/cmd.asm +++ b/apps/ed/cmd.asm @@ -25,7 +25,9 @@ cmdParse: ld a, (hl) cp 'q' - jr z, .quit + jr z, .simpleCmd + cp 'w' + jr z, .simpleCmd ld ix, CMD_ADDR1 call .readAddr ret nz @@ -67,7 +69,7 @@ cmdParse: ld (CMD_TYPE), a ret ; Z already set -.quit: +.simpleCmd: ; Z already set ld (CMD_TYPE), a ret diff --git a/apps/ed/io.asm b/apps/ed/io.asm index e96737b..4cf92bc 100644 --- a/apps/ed/io.asm +++ b/apps/ed/io.asm @@ -32,7 +32,7 @@ ioInit: ld ix, IO_FILE_HDL jp fsPutC .blkdev: - .dw .fsGetC, unsetZ + .dw .fsGetC, .fsPutC ioGetC: push ix @@ -61,3 +61,33 @@ ioTell: call _blkTell pop ix ret + +ioSetSize: + push ix + ld ix, IO_FILE_HDL + call fsSetSize + pop ix + ret + +; Write string (HL) in current file. Ends line with LF. +ioPutLine: + push hl +.loop: + ld a, (hl) + or a + jr z, .loopend ; null, we're finished + call ioPutC + jr nz, .error + inc hl + jr .loop +.loopend: + ; Wrote the whole line, write ending LF + ld a, 0x0a + call ioPutC + jr z, .end ; success + ; continue to error +.error: + call unsetZ +.end: + pop hl + ret diff --git a/apps/ed/main.asm b/apps/ed/main.asm index 1f197ff..a83c343 100644 --- a/apps/ed/main.asm +++ b/apps/ed/main.asm @@ -36,6 +36,7 @@ ; fsOpen ; fsGetC ; fsPutC +; fsSetSize ; intoHL ; printstr ; printcrlf @@ -69,6 +70,8 @@ edMain: ld a, (CMD_TYPE) cp 'q' jr z, .doQuit + cp 'w' + jr z, .doWrite ; The rest of the commands need an address call edReadAddrs jr nz, .error @@ -85,6 +88,26 @@ edMain: xor a ret +.doWrite: + ld a, 3 ; seek beginning + call ioSeek + ld de, 0 ; cur line +.writeLoop: + push de \ pop hl + call bufGetLine ; --> buffer in (HL) + jr nz, .writeEnd + call ioPutLine + jr nz, .error + inc de + jr .writeLoop +.writeEnd: + ; Set new file size + call ioTell + call ioSetSize + ; for now, writing implies quitting + ; TODO: reload buffer + xor a + ret .doDel: ; bufDelLines expects an exclusive upper bound, which is why we inc DE. inc de @@ -114,12 +137,12 @@ edMain: jr .doPrint .doPrintEnd: ld (ED_CURLINE), hl - jr .mainLoop + jp .mainLoop .error: ld a, '?' call stdioPutC call printcrlf - jr .mainLoop + jp .mainLoop ; Transform an address "cmd" in IX into an absolute address in HL. diff --git a/kernel/fs.asm b/kernel/fs.asm index b3e28b2..4c70e8d 100644 --- a/kernel/fs.asm +++ b/kernel/fs.asm @@ -425,7 +425,6 @@ fsPlaceH: pop af ret -; 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: @@ -441,24 +440,20 @@ fsWithinBounds: .outOfBounds: jp unsetZ ; returns -; Adjust, if needed, file size of handle (IX) to HL+1. -; This adjustment only happens if this makes file size grow. -fsAdjustBounds: - call fsWithinBounds - ret z - ; Not within bounds? let's increase them - push hl +; Set size of file handle (IX) to value in HL. +; This writes directly in handle's metadata. +fsSetSize: + push hl ; --> lvl 1 ld hl, 0 call fsPlaceH ; fs blkdev is now at beginning of content ; we need the blkdev to be on filesize's offset ld hl, FS_METASIZE-FS_META_FSIZE_OFFSET ld a, BLOCKDEV_SEEK_BACKWARD call fsblkSeek - pop hl + pop hl ; <-- lvl 1 ; blkdev is at the right spot, HL is back to its original value, let's - ; write it. - push hl - inc hl ; We write HL+1, remember + ; write it both in the metadata block and in its file handle's cache. + push hl ; --> lvl 1 ; now let's write our new filesize both in blkdev and in file handle's ; cache. ld a, l @@ -467,7 +462,7 @@ fsAdjustBounds: ld a, h ld (ix+5), a call fsblkPutC - pop hl + pop hl ; <-- lvl 1 xor a ; ensure Z ret @@ -488,7 +483,7 @@ fsGetC: pop hl ret -; Write byte A in handle (IX) and advance the handle's position. +; Write byte A in handle (IX) at position HL. ; Z is set on success, unset if handle is at the end of the file. ; TODO: detect end of block alloc fsPutC: @@ -496,7 +491,11 @@ fsPutC: call fsPlaceH call fsblkPutC pop hl - jp fsAdjustBounds ; returns + ; if HL is out of bounds, increase bounds + call fsWithinBounds + ret z + inc hl ; our filesize is now HL+1 + jp fsSetSize ; 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. diff --git a/tools/emul/shell/shell_.asm b/tools/emul/shell/shell_.asm index a522124..acc61c2 100644 --- a/tools/emul/shell/shell_.asm +++ b/tools/emul/shell/shell_.asm @@ -28,6 +28,7 @@ jp fsOpen jp fsGetC jp fsPutC + jp fsSetSize jp cpHLDE jp parseArgs jp printstr diff --git a/tools/emul/shell/user.h b/tools/emul/shell/user.h index c2d1379..43855ff 100644 --- a/tools/emul/shell/user.h +++ b/tools/emul/shell/user.h @@ -21,13 +21,14 @@ .equ fsOpen 0x2d .equ fsGetC 0x30 .equ fsPutC 0x33 -.equ cpHLDE 0x36 -.equ parseArgs 0x39 -.equ printstr 0x3c -.equ _blkGetC 0x3f -.equ _blkPutC 0x42 -.equ _blkSeek 0x45 -.equ _blkTell 0x48 -.equ printcrlf 0x4b -.equ stdioPutC 0x4e -.equ stdioReadLine 0x51 +.equ fsSetSize 0x36 +.equ cpHLDE 0x39 +.equ parseArgs 0x3c +.equ printstr 0x3f +.equ _blkGetC 0x42 +.equ _blkPutC 0x45 +.equ _blkSeek 0x48 +.equ _blkTell 0x4b +.equ printcrlf 0x4e +.equ stdioPutC 0x51 +.equ stdioReadLine 0x54