@@ -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 | |||
@@ -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 | |||
@@ -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 |
@@ -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. | |||
@@ -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. | |||
@@ -28,6 +28,7 @@ | |||
jp fsOpen | |||
jp fsGetC | |||
jp fsPutC | |||
jp fsSetSize | |||
jp cpHLDE | |||
jp parseArgs | |||
jp printstr | |||
@@ -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 |