commit a6c46ca861ad644a3ca48db0860433e72209e225
parent 4f733f7f0e71fd75c6368a47f7460ac1b05d87c1
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Fri, 23 Dec 2022 13:53:21 -0500
Add non-blocking key? word
Change the POSIX VM to allow non-blocking interactive input. This allows the
introduction of "key?" to the system, which "key" now wraps in a blocking way.
Diffstat:
9 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/Makefile b/Makefile
@@ -43,7 +43,7 @@ rpi.img: dusk $(ALLSRCS)
.PHONY: run
run: dusk
- stty -icanon -echo; ./dusk ; stty icanon echo
+ stty -icanon -echo min 0; ./dusk ; stty icanon echo
.PHONY: test
test: dusk
diff --git a/README.md b/README.md
@@ -190,10 +190,11 @@ interactive prompt.
Documentation lives in `fs/doc`. You can begin with [doc/index][docs]. Type
`bye` to quit.
-Dusk OS expects a raw input. With a regular TTY, your input will be buffered
-and echoed twice. To avoid that, you can invoke it like this:
+Dusk OS expects a non-canonical raw input. With a regular TTY, your input will
+be buffered and echoed twice and reads to it will be blocking. We don't want
+that. To avoid that, you can invoke it like this:
- (stty -icanon -echo; ./dusk; stty icanon echo)
+ (stty -icanon -echo min 0; ./dusk; stty icanon echo)
`make run` does this for you.
diff --git a/fs/doc/dict.txt b/fs/doc/dict.txt
@@ -293,6 +293,8 @@ rebind 'data 'bind --
## I/O
+key? -- c? f Poll system interactive input source for keypress. If
+ there is one, f=1 and c is set. Otherwise, f=0.
key -- c Read next character from system interactive input source.
in< -- c Read next character from system input source.
"< -- c Read from in< and apply literal escapes. c=-1 when " is
diff --git a/fs/sys/ps2.fs b/fs/sys/ps2.fs
@@ -86,13 +86,13 @@ $8d 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
else 2drop then
then ;
-\ Poll ps2@, apply shift logic, return the corresponding ASCII code.
-: ps2keyset1 ( -- c )
- begin
- begin ps2@? until ( kc ) ps2kcset1>ascii ( is-released c-or-0 )
+\ Poll ps2@, apply shift logic, return the corresponding ASCII code, if a key
+\ has been pressed.
+: ps2keyset1? ( -- c? f )
+ ps2@? if ( kc ) ps2kcset1>ascii ( is-released c-or-0 )
swap if \ released, do nothing
drop 0
else \ pressed
- dup $80 and if drop 0 then
- then ( c-or-0 )
- ?dup until ( c ) ;
+ dup $80 and if drop 0 else 1 then
+ then ( c? f )
+ else 0 then ;
diff --git a/fs/sys/rdln.fs b/fs/sys/rdln.fs
@@ -12,6 +12,7 @@ in) value in>
else ( ptr c ) \ non-BS
dup emitv dup rot c!+ ( c ptr+1 ) dup in) = rot SPC < or ( ptr+1 f )
then ;
+: key begin key? until ;
: rdln
in( LNSZ SPC fill S" ok\n" stype
in( begin key lntype until drop nl> ;
diff --git a/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs
@@ -113,7 +113,6 @@ HERE ivalue here
EMIT ialias emit
ABORT ialias abort
MAIN ialias main
-alias abort key
: &+ ( n -- ) doer , does> @ + ;
: &@ ( n -- ) doer , does> @ @ ;
diff --git a/fs/xcomp/i386/pc/init.fs b/fs/xcomp/i386/pc/init.fs
@@ -41,7 +41,7 @@ f<< /sys/ps2.fs
8042ps2$
' 8042kbd@? to (ps2@?)
-' ps2keyset1 to key
+: key? ps2keyset1? ;
f<< /drv/pc/a20.fs
a20$
diff --git a/posix/glue.fs b/posix/glue.fs
@@ -1,4 +1,3 @@
-' (key) to key
: _ doer ' , does> nip @ execute ;
_ _:child _fchild _ _:open _fopen _ _:info _finfo
create _POSIXFS
diff --git a/posix/vm.c b/posix/vm.c
@@ -273,8 +273,15 @@ static void STDOUT() { // op: 15
write(STDOUT_FILENO, &c, 1);
}
-static void KEY() { // op: 16
- ppush(getc(stdin));
+// ( -- c? f )
+static void MAYBEKEY() { // op: 16
+ char c;
+ if (read(STDIN_FILENO, &c, 1) == 1) {
+ ppush(c);
+ ppush(1);
+ } else {
+ ppush(0);
+ }
}
static void DUP() { // op: 18
@@ -1033,7 +1040,7 @@ static void DRVWR() { // op: 6a
static void (*ops[OPCNT])() = {
JUMP, CALL, RET, LIT, BYE, BYEFAIL, QUIT, ABORT_,
EXECUTE, CELL, DOES, SLIT, BR, CBR, NEXT, NULL,
- PSADD, PSADDWR, PSADDR, PSADDRWR, BOOTRD, STDOUT, KEY, NULL,
+ PSADD, PSADDWR, PSADDR, PSADDRWR, BOOTRD, STDOUT, MAYBEKEY, NULL,
DUP, CDUP, SWAP, OVER, ROT, ROTR, NIP, TUCK,
RSADD, RSADDWR, RSADDR, RSADDRWR, SCNT, RCNT, NULL, NULL,
FETCH, STORE, ADDSTORE, FETCHSTORE, FETCHADD, STOREADD, IFETCHADD, ISTOREADD,
@@ -1049,7 +1056,7 @@ static void (*ops[OPCNT])() = {
static char *opnames[OPCNT] = {
NULL, NULL, NULL, NULL, "bye", "byefail", "quit", "(abort)",
"execute", "(cell)", "(does)", "(s)", "(br)", "(?br)", "(next)", NULL,
- NULL, "p+,", NULL, "p',", "boot<", "(emit)", "(key)", "drop",
+ NULL, "p+,", NULL, "p',", "boot<", "(emit)", "key?", "drop",
"dup", "?dup", "swap", "over", "rot", "rot>", "nip", "tuck",
NULL, "r+,", NULL, "r',", "scnt", "rcnt", NULL, NULL,
"@", "!", "+!", "@!", "@+", "!+", "@@+", "@!+",