TaliForth2 icon indicating copy to clipboard operation
TaliForth2 copied to clipboard

Remove KEY? and zp havekey vector

Open patricksurry opened this issue 1 year ago • 5 comments

Tali does not currenly implement KEY? at all (it expects blocking behavior from kernel_getc), so I believe it's totally safe to remove havekey: at this point in time. The issue with KEY? is that not all input sources allow you to check if there is a char available without actually trying to read one, so it was left unimplemented with the assumption that a user could implement it themselves if they wanted it (see https://github.com/SamCoVT/TaliForth2/issues/51).

patricksurry avatar Mar 29 '24 10:03 patricksurry

alternatively we could hook it up since c65 supports a non-blocking peekc

patricksurry avatar Apr 07 '24 11:04 patricksurry

It might not be ridiculous to hook it up, but we'll need to document how the linkage works. The other routines get/put the char in A and Tali gets/puts them on the Forth stack. We could either use A as a flag, or use the carry flag. For py65mon, which doesn't have a peekc, we can implement a single byte buffer (using byte $00 to indicate no data in buffer).

SamCoVT avatar Apr 07 '24 23:04 SamCoVT

Perhaps it could work the same way? Have KEY? ( -- flag' ) where flag' is 0 or $ff00 | chr. Or maybe ( -- false | key true )

Or is it better to just have KEY? ( -- true | false ) then KEY to fetch the char?

Or am I missing your point?

patricksurry avatar Apr 08 '24 10:04 patricksurry

Standard FORTH is to have key? return a flag and key actually fetch the character (with blocking I/O if none is available).

The "kernel_xxx" functions currently do not interact with the Forth stack at all, and accept or return the char in A. The forth words for key and type call the user's kernel_xxx function (indirectly, using the I/O vectors in zero page) and then move the data to/from the Forth data stack. We would need to document how the presence of the character is indicated, and write a Forth word key? that calls (indirectly, through zero page) the user's kernel function and puts either true or false on the Forth data stack.

There should also be a Forth helper word to return the address of the vector (in zero page) so that it can be replaced from Forth. The current words for accessing the I/O vectors are input and output, so perhaps input? makes sense for the vector that key? will ultimately use.

SamCoVT avatar Apr 08 '24 15:04 SamCoVT

That makes sense. Depending on your simulator / hardware it seems like the user might prefer to provide kbhit along with the current blocking getc (so the user owns the character buffer) or replace both with a non-blocking peekc (where tali owns the buffer).

  • kernel_getc - blocking, return a character in A
  • kernel_kbhit - non-blocking, return non-zero if a key is ready be fetched by getc
  • kernel_peekc - non-blocking, return a character in A or 0

key? maps easily to the getc + kbhit case, and with some conditional compilation tali could provide default getc/kbhit implementations if the user prefers to provide peekc instead (like for pymon or c65). I'll probably have a go at that.

patricksurry avatar May 14 '24 11:05 patricksurry