SamCoVT / TaliForth2

A Subroutine Threaded Code (STC) ANSI-like Forth for the 65c02
Other
29 stars 5 forks source link

Remove KEY? and zp havekey vector #62

Closed patricksurry closed 3 months ago

patricksurry commented 5 months ago

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 commented 5 months ago

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

SamCoVT commented 5 months ago

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).

patricksurry commented 5 months ago

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?

SamCoVT commented 5 months ago

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.

patricksurry commented 4 months ago

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).

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.