1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-30 21:08:05 +11:00

apps/ed: add the concept of "current line"

This commit is contained in:
Virgil Dupras 2019-07-13 15:28:44 -04:00
parent e0f2a71dfc
commit 951dd2206d
4 changed files with 85 additions and 17 deletions

View File

@ -9,5 +9,6 @@
#include "ed/io.asm" #include "ed/io.asm"
.equ BUF_RAMSTART IO_RAMEND .equ BUF_RAMSTART IO_RAMEND
#include "ed/buf.asm" #include "ed/buf.asm"
.equ ED_RAMSTART BUF_RAMEND
#include "ed/main.asm" #include "ed/main.asm"

View File

@ -57,19 +57,27 @@
; stdioPutC ; stdioPutC
; stdioReadC ; stdioReadC
; unsetZ ; unsetZ
;
; *** Variables ***
;
.equ ED_CURLINE ED_RAMSTART
.equ ED_RAMEND ED_CURLINE+2
edMain: edMain:
; diverge from UNIX: start at first line
ld hl, 0
ld (ED_CURLINE), hl
; Fill line buffer ; Fill line buffer
.loop: .fillLoop:
call blkTell ; --> HL call blkTell ; --> HL
call blkGetC call blkGetC
jr nz, edLoop jr nz, .mainLoop
call bufAddLine call bufAddLine
call ioGetLine call ioGetLine
jr .loop jr .fillLoop
; Continue to loop
edLoop: .mainLoop:
ld a, ':' ld a, ':'
call stdioPutC call stdioPutC
.inner: .inner:
@ -80,33 +88,82 @@ edLoop:
call stdioGetLine call stdioGetLine
call .processLine call .processLine
ret z ret z
jr edLoop jr .mainLoop
; Sets Z if we need to quit ; Sets Z if we need to quit
.processLine: .processLine:
ld a, (hl) ld a, (hl)
cp 'q' cp 'q'
ret z ret z
call parseDecimal call edReadAddr
jr z, .processNumber jr z, .processNumber
jr .error jr .processError
.processNumber: .processNumber:
; number is in IX ; number is in DE
; Because we don't have a line buffer yet, let's simply print seek ; We expect HL (rest of the cmdline) to be a null char, otherwise it's
; offsets. ; garbage
push ix \ pop hl ld a, (hl)
dec hl ; from 1-based to zero-based or a
jr nz, .processError
ex de, hl
ld (ED_CURLINE), hl
call bufGetLine call bufGetLine
jr nz, .error jr nz, .processError
call printstr call printstr
call printcrlf call printcrlf
; continue to end ; continue to end
.processEnd: .processEnd:
call printcrlf call printcrlf
jp unsetZ jp unsetZ
.error: .processError:
ld a, '?' ld a, '?'
call stdioPutC call stdioPutC
call printcrlf call printcrlf
jp unsetZ jp unsetZ
; Parse the string at (HL) and sets its corresponding address in DE, properly
; considering implicit values (current address when nothing is specified).
; advances HL to the char next to the last parsed char.
; Sets Z on success, unset on error. Line out of bounds isn't an error. Only
; overflows.
edReadAddr:
ld a, (hl)
call parseDecimalDigit
jr c, .NaN
push bc
push ix
push hl
.loop:
inc hl
ld a, (hl)
call parseDecimalDigit
jr nc, .loop
; We're at the first non-digit char. Let's save it because we're going
; to temporarily replace it with a null.
ld b, a
xor a
ld (hl), a
; Now, let's go back to the beginning of the string and parse it.
; but before we do this, let's save the end of string in DE
ex de, hl
pop hl
call parseDecimal
; Z is set properly at this point. nothing touches Z below.
ld a, b
ld (de), a
ex de, hl ; put end of string back from DE to HL
; Put addr in its final register, DE
push ix \ pop de
dec de ; from 1-based to 0-base. 16bit doesn't affect flags.
pop ix
pop bc
ret
.NaN:
; Not a number, return current line
push hl
ld hl, (ED_CURLINE)
ex de, hl
pop hl
cp a ; ensure Z
ret

View File

@ -19,10 +19,10 @@ parseDecimalDigit:
; Parse string at (HL) as a decimal value and return value in IX under the ; Parse string at (HL) as a decimal value and return value in IX under the
; same conditions as parseLiteral. ; same conditions as parseLiteral.
; Sets Z on success, unset on error.
parseDecimal: parseDecimal:
push hl push hl
push de push de
push bc
ld ix, 0 ld ix, 0
.loop: .loop:
@ -52,10 +52,11 @@ parseDecimal:
inc hl inc hl
jr .loop jr .loop
cp a ; ensure Z
jr .end
.error: .error:
call unsetZ call unsetZ
.end: .end:
pop bc
pop de pop de
pop hl pop hl
ret ret

View File

@ -160,6 +160,15 @@ stdioReadC:
.complete: .complete:
; The line in our buffer is complete. ; The line in our buffer is complete.
; But before we do that, let's take care of a special case: the empty
; line. If we didn't add any character since the last "complete", then
; our buffer's content is the content from the last time. Let's set this
; to an empty string.
ld a, (STDIO_BUFIDX)
or a
jr nz, .completeSkip
ld (STDIO_BUF), a
.completeSkip:
xor a ; sets Z xor a ; sets Z
ld (STDIO_BUFIDX), a ld (STDIO_BUFIDX), a
ret ret