duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

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:
MMakefile | 2+-
MREADME.md | 7++++---
Mfs/doc/dict.txt | 2++
Mfs/sys/ps2.fs | 14+++++++-------
Mfs/sys/rdln.fs | 1+
Mfs/xcomp/bootlo.fs | 1-
Mfs/xcomp/i386/pc/init.fs | 2+-
Mposix/glue.fs | 1-
Mposix/vm.c | 15+++++++++++----
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, "@", "!", "+!", "@!", "@+", "!+", "@@+", "@!+",