mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 22:08:05 +11:00
stdio: add stdioReadC
A routine to conveniently read lines from TTY. Extracted from shell. Will be used in other places.
This commit is contained in:
parent
252d71f1b8
commit
e01ee170cb
@ -35,10 +35,6 @@
|
|||||||
; number of entries in shellCmdTbl
|
; number of entries in shellCmdTbl
|
||||||
.equ SHELL_CMD_COUNT 6+SHELL_EXTRA_CMD_COUNT
|
.equ SHELL_CMD_COUNT 6+SHELL_EXTRA_CMD_COUNT
|
||||||
|
|
||||||
; Size of the shell command buffer. If a typed command reaches this size, the
|
|
||||||
; command is flushed immediately (same as pressing return).
|
|
||||||
.equ SHELL_BUFSIZE 0x20
|
|
||||||
|
|
||||||
; *** VARIABLES ***
|
; *** VARIABLES ***
|
||||||
; Memory address that the shell is currently "pointing at" for peek, load, call
|
; Memory address that the shell is currently "pointing at" for peek, load, call
|
||||||
; operations. Set with mptr.
|
; operations. Set with mptr.
|
||||||
@ -48,13 +44,8 @@
|
|||||||
; written to after parsing.
|
; written to after parsing.
|
||||||
.equ SHELL_CMD_ARGS SHELL_MEM_PTR+2
|
.equ SHELL_CMD_ARGS SHELL_MEM_PTR+2
|
||||||
|
|
||||||
; Command buffer. We read types chars into this buffer until return is pressed
|
|
||||||
; This buffer is null-terminated and we don't keep an index around: we look
|
|
||||||
; for the null-termination every time we write to it. Simpler that way.
|
|
||||||
.equ SHELL_BUF SHELL_CMD_ARGS+PARSE_ARG_MAXCOUNT
|
|
||||||
|
|
||||||
; Pointer to a hook to call when a cmd name isn't found
|
; Pointer to a hook to call when a cmd name isn't found
|
||||||
.equ SHELL_CMDHOOK SHELL_BUF+SHELL_BUFSIZE
|
.equ SHELL_CMDHOOK SHELL_CMD_ARGS+PARSE_ARG_MAXCOUNT
|
||||||
|
|
||||||
; Pointer to a routine to call at each shell loop interation
|
; Pointer to a routine to call at each shell loop interation
|
||||||
.equ SHELL_LOOPHOOK SHELL_CMDHOOK+2
|
.equ SHELL_LOOPHOOK SHELL_CMDHOOK+2
|
||||||
@ -65,14 +56,13 @@ shellInit:
|
|||||||
xor a
|
xor a
|
||||||
ld (SHELL_MEM_PTR), a
|
ld (SHELL_MEM_PTR), a
|
||||||
ld (SHELL_MEM_PTR+1), a
|
ld (SHELL_MEM_PTR+1), a
|
||||||
ld (SHELL_BUF), a
|
|
||||||
ld hl, noop
|
ld hl, noop
|
||||||
ld (SHELL_CMDHOOK), hl
|
ld (SHELL_CMDHOOK), hl
|
||||||
ld (SHELL_LOOPHOOK), hl
|
ld (SHELL_LOOPHOOK), hl
|
||||||
|
|
||||||
; print welcome
|
; print welcome
|
||||||
ld hl, .welcome
|
ld hl, .welcome
|
||||||
jp printstr ; returns
|
jp printstr
|
||||||
|
|
||||||
.welcome:
|
.welcome:
|
||||||
.db "Collapse OS", ASCII_CR, ASCII_LF, "> ", 0
|
.db "Collapse OS", ASCII_CR, ASCII_LF, "> ", 0
|
||||||
@ -84,52 +74,12 @@ shellLoop:
|
|||||||
ld ix, (SHELL_LOOPHOOK)
|
ld ix, (SHELL_LOOPHOOK)
|
||||||
call callIX
|
call callIX
|
||||||
; Then, let's wait until something is typed.
|
; Then, let's wait until something is typed.
|
||||||
call stdioGetC
|
call stdioReadC
|
||||||
jr nz, shellLoop ; nothing typed? loop
|
jr nz, shellLoop ; not done? loop
|
||||||
; got it. Now, is it a CR or LF?
|
; We're done. Process line.
|
||||||
cp ASCII_CR
|
|
||||||
jr z, .do ; char is CR? do!
|
|
||||||
cp ASCII_LF
|
|
||||||
jr z, .do ; char is LF? do!
|
|
||||||
cp ASCII_DEL
|
|
||||||
jr z, .delchr
|
|
||||||
cp ASCII_BS
|
|
||||||
jr z, .delchr
|
|
||||||
|
|
||||||
; Echo the received character right away so that we see what we type
|
|
||||||
call stdioPutC
|
|
||||||
|
|
||||||
; Ok, gotta add it do the buffer
|
|
||||||
; save char for later
|
|
||||||
ex af, af'
|
|
||||||
ld hl, SHELL_BUF
|
|
||||||
xor a ; look for null
|
|
||||||
call findchar ; HL points to where we need to write
|
|
||||||
; A is the number of chars in the buf
|
|
||||||
cp SHELL_BUFSIZE-1 ; -1 is because we always want to keep our
|
|
||||||
; last char at zero.
|
|
||||||
jr z, .do ; end of buffer reached? buffer is full. do!
|
|
||||||
|
|
||||||
; bring the char back in A
|
|
||||||
ex af, af'
|
|
||||||
; Buffer not full, not CR or LF. Let's put that char in our buffer and
|
|
||||||
; read again.
|
|
||||||
ld (hl), a
|
|
||||||
; Now, write a zero to the next byte to properly terminate our string.
|
|
||||||
inc hl
|
|
||||||
xor a
|
|
||||||
ld (hl), a
|
|
||||||
|
|
||||||
jr shellLoop
|
|
||||||
|
|
||||||
.do:
|
|
||||||
call printcrlf
|
call printcrlf
|
||||||
ld hl, SHELL_BUF
|
call stdioGetLine
|
||||||
call shellParse
|
call shellParse
|
||||||
; empty our buffer by writing a zero to its first char
|
|
||||||
xor a
|
|
||||||
ld (hl), a
|
|
||||||
|
|
||||||
ld hl, .prompt
|
ld hl, .prompt
|
||||||
call printstr
|
call printstr
|
||||||
jr shellLoop
|
jr shellLoop
|
||||||
@ -137,28 +87,6 @@ shellLoop:
|
|||||||
.prompt:
|
.prompt:
|
||||||
.db "> ", 0
|
.db "> ", 0
|
||||||
|
|
||||||
.delchr:
|
|
||||||
ld hl, SHELL_BUF
|
|
||||||
ld a, (hl)
|
|
||||||
or a ; cp 0
|
|
||||||
jr z, shellLoop ; buffer empty? nothing to do
|
|
||||||
; buffer not empty, let's delete
|
|
||||||
xor a ; look for null
|
|
||||||
call findchar ; HL points to end of buf
|
|
||||||
dec hl ; the char before it
|
|
||||||
xor a
|
|
||||||
ld (hl), a ; set to zero
|
|
||||||
; Char deleted in buffer, now send BS + space + BS for the terminal
|
|
||||||
; to clear its previous char
|
|
||||||
ld a, ASCII_BS
|
|
||||||
call stdioPutC
|
|
||||||
ld a, ' '
|
|
||||||
call stdioPutC
|
|
||||||
ld a, ASCII_BS
|
|
||||||
call stdioPutC
|
|
||||||
jr shellLoop
|
|
||||||
|
|
||||||
|
|
||||||
; Parse command (null terminated) at HL and calls it
|
; Parse command (null terminated) at HL and calls it
|
||||||
shellParse:
|
shellParse:
|
||||||
push af
|
push af
|
||||||
|
111
kernel/stdio.asm
111
kernel/stdio.asm
@ -1,20 +1,36 @@
|
|||||||
; stdio
|
; stdio
|
||||||
;
|
;
|
||||||
; Allows other modules to print to "standard out", and get data from "stamdard
|
; Allows other modules to print to "standard out", and get data from "standard
|
||||||
; in", that is, the console through which the user is connected in a decoupled
|
; in", that is, the console through which the user is connected in a decoupled
|
||||||
; manner.
|
; manner.
|
||||||
;
|
;
|
||||||
; *** VARIABLES ***
|
; *** Consts ***
|
||||||
|
; Size of the readline buffer. If a typed line reaches this size, the line is
|
||||||
|
; flushed immediately (same as pressing return).
|
||||||
|
.equ STDIO_BUFSIZE 0x20
|
||||||
|
|
||||||
|
; *** Variables ***
|
||||||
; Used to store formatted hex values just before printing it.
|
; Used to store formatted hex values just before printing it.
|
||||||
.equ STDIO_HEX_FMT STDIO_RAMSTART
|
.equ STDIO_HEX_FMT STDIO_RAMSTART
|
||||||
.equ STDIO_GETC STDIO_HEX_FMT+2
|
.equ STDIO_GETC STDIO_HEX_FMT+2
|
||||||
.equ STDIO_PUTC STDIO_GETC+2
|
.equ STDIO_PUTC STDIO_GETC+2
|
||||||
.equ STDIO_RAMEND STDIO_PUTC+2
|
|
||||||
|
; Line buffer. We read types chars into this buffer until return is pressed
|
||||||
|
; This buffer is null-terminated and we don't keep an index around: we look
|
||||||
|
; for the null-termination every time we write to it. Simpler that way.
|
||||||
|
.equ STDIO_BUF STDIO_PUTC+2
|
||||||
|
|
||||||
|
; Index where the next char will go in stdioGetC.
|
||||||
|
.equ STDIO_BUFIDX STDIO_BUF+STDIO_BUFSIZE
|
||||||
|
.equ STDIO_RAMEND STDIO_BUFIDX+1
|
||||||
|
|
||||||
; Sets GetC to the routine where HL points to and PutC to DE.
|
; Sets GetC to the routine where HL points to and PutC to DE.
|
||||||
stdioInit:
|
stdioInit:
|
||||||
ld (STDIO_GETC), hl
|
ld (STDIO_GETC), hl
|
||||||
ld (STDIO_PUTC), de
|
ld (STDIO_PUTC), de
|
||||||
|
xor a
|
||||||
|
ld (STDIO_BUF), a
|
||||||
|
ld (STDIO_BUFIDX), a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
stdioGetC:
|
stdioGetC:
|
||||||
@ -88,3 +104,92 @@ printHexPair:
|
|||||||
call printHex
|
call printHex
|
||||||
pop af
|
pop af
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; Call stdioGetC and put the result in the buffer. Sets Z according to whether
|
||||||
|
; the buffer is "complete", that is, whether CR or LF have been pressed or if
|
||||||
|
; the the buffer is full. Z is set if the line is "complete", unset if not.
|
||||||
|
; The next call to stdioReadC after a completed line will start a new line.
|
||||||
|
;
|
||||||
|
; This routine also takes care of echoing received characters back to the TTY.
|
||||||
|
;
|
||||||
|
; Note that this routine doesn't bother returning the typed character.
|
||||||
|
stdioReadC:
|
||||||
|
; Let's wait until something is typed.
|
||||||
|
call stdioGetC
|
||||||
|
jr nz, stdioReadC ; nothing typed? loop
|
||||||
|
; got it. Now, is it a CR or LF?
|
||||||
|
cp ASCII_CR
|
||||||
|
jr z, .complete ; char is CR? buffer complete!
|
||||||
|
cp ASCII_LF
|
||||||
|
jr z, .complete
|
||||||
|
cp ASCII_DEL
|
||||||
|
jr z, .delchr
|
||||||
|
cp ASCII_BS
|
||||||
|
jr z, .delchr
|
||||||
|
|
||||||
|
; Echo the received character right away so that we see what we type
|
||||||
|
call stdioPutC
|
||||||
|
|
||||||
|
; Ok, gotta add it do the buffer
|
||||||
|
; save char for later
|
||||||
|
ex af, af'
|
||||||
|
ld a, (STDIO_BUFIDX)
|
||||||
|
push hl ;<|
|
||||||
|
ld hl, STDIO_BUF ; |
|
||||||
|
; make HL point to dest spot |
|
||||||
|
call addHL ; |
|
||||||
|
; Write our char down |
|
||||||
|
ex af, af' ; |
|
||||||
|
ld (hl), a ; |
|
||||||
|
; follow up with a null char |
|
||||||
|
inc hl ; |
|
||||||
|
xor a ; |
|
||||||
|
ld (hl), a ; |
|
||||||
|
pop hl ;<|
|
||||||
|
; inc idx, which still is in AF'
|
||||||
|
ex af, af'
|
||||||
|
inc a
|
||||||
|
cp STDIO_BUFSIZE-1 ; -1 is because we always want to keep our
|
||||||
|
; last char at zero.
|
||||||
|
jr z, .complete ; end of buffer reached? buffer is full.
|
||||||
|
|
||||||
|
; not complete. save idx back
|
||||||
|
ld (STDIO_BUFIDX), a
|
||||||
|
; Z already unset
|
||||||
|
ret
|
||||||
|
|
||||||
|
.complete:
|
||||||
|
; The line in our buffer is complete.
|
||||||
|
xor a ; sets Z
|
||||||
|
ld (STDIO_BUFIDX), a
|
||||||
|
ret
|
||||||
|
|
||||||
|
.delchr:
|
||||||
|
ld a, (STDIO_BUFIDX)
|
||||||
|
or a
|
||||||
|
jp z, unsetZ ; buf empty? nothing to do
|
||||||
|
; buffer not empty, let's go back one char and set a null char there.
|
||||||
|
dec a
|
||||||
|
ld (STDIO_BUFIDX), a
|
||||||
|
push hl ;<|
|
||||||
|
ld hl, STDIO_BUF ; |
|
||||||
|
; make HL point to dest spot |
|
||||||
|
call addHL ; |
|
||||||
|
xor a ; |
|
||||||
|
ld (hl), a ; |
|
||||||
|
pop hl ;<|
|
||||||
|
; Char deleted in buffer, now send BS + space + BS for the terminal
|
||||||
|
; to clear its previous char
|
||||||
|
ld a, ASCII_BS
|
||||||
|
call stdioPutC
|
||||||
|
ld a, ' '
|
||||||
|
call stdioPutC
|
||||||
|
ld a, ASCII_BS
|
||||||
|
call stdioPutC
|
||||||
|
jp unsetZ
|
||||||
|
|
||||||
|
|
||||||
|
; Make HL point to the line buffer. It is always null terminated.
|
||||||
|
stdioGetLine:
|
||||||
|
ld hl, STDIO_BUF
|
||||||
|
ret
|
||||||
|
Loading…
Reference in New Issue
Block a user