...
As of September 19, 2023, the core and ROM code that implement this feature are here:
Core PR 720, soon to be merged to the development branch (v0.96 candidate)
ROM branch 7_keyscan, intended for upcoming beta release 920387 (v0.96 candidate)The latest core from the development branch, at least
20230924
build #61ROM beta release 920388
File bugs in the mega65-rom-public repo, and contact @dddaaannn on Discord for more information.
Tip: If you notice buggy behavior that may be attributed to ROM 920387920388, try reproducing it, then try again in ROM 920386, which uses the original keyboard scanner. You do not need to go back to the previous version of the core for this to be usefultest. Include reproduction steps and a description of the behavior in both ROMs in your bug report.
ROM 920388 will not work with older cores. Older ROMs work with the latest core, so you may want to install the development core in slot 1, use 920377 or 920386 as your default MEGA65.ROM
, then put 920388 in a non-default ROM slot such as MEGA652.ROM
(where 2
is the ROM slot number: hold the "2" key during boot to select it). If you use ROM 920388 with an old core, typing will not work.
Known issues
The virtual keyboard registers are glitchy with the new keyboard scanner with regards to modifier keys. The
m65
tool’s typing feature has been updated to accommodate this.MegaAssembler and Coffeebreak Compiler are not working, apparently getting 0 from GETKEY for all typing events. Not all uses of GETKEY are affected. This is still being researched.
Test plan
This change is not expected to break any ROM features or MEGA65 applications. Software that uses the ROM’s getin
entry point will benefit from the new typing accuracy automatically. This includes BASIC programs that use the GET
/ GETKEY
commands. The change is expected to be compatible with existing applications that use the documented ASCIIKEY register, or do their own keyboard scanning of the CIA lines. It is not expected to affect GO64 mode or older ROMs running on the latest core. (Legacy-style CIA keyboard scanning in software still functions.)
In theory, this change might violate pre- and post-conditions of keyboard related KERNAL entry points, described later in this document. In the context of the MEGA65, these behaviors are undocumented to an extent that MEGA65 applications should not be using them. For example, C64 coders might be used to manipulating the KERNAL’s keyboard buffer directly, and this no longer works the same way in the MEGA65. The keyboard buffer location and behavior is not documented for direct access by a program in the MEGA65 ROM.
...
The legacy scanner potentially misses keystrokes because of a limitation in how keys are wired to the CIA chip. The CIA can only detect so many keys pressed at one time, constrained to a pattern in the wiring. Fast typists tend to press the next key before releasing the previous key, and will notice that specific keys in specific words tend to get skipped more than others. (Personally, I can’t type the word “MOUNT” at my usual typing speed using the legacy keyboard scanner. It always comes out as “MONT” unless I slow down.) The MEGA65 core fully replicates this behavior of CIA chips.
...
ASCIIKEY $d610 represents the event as an ASCII value, or $ff if there is no equivalent ASCII value for the event.
PETSCIIKEY $d619 represents the event as a PETSCII value or $ff.
MODKEY $d611$d60a[0:6] represents the modifier keys that were held down during the typing event. (Note that ASCIIKEY and PETSCIIKEY take modifier keys into account, such as Shift plus a letter resulting in a capital letter.)
...
The ASCIIKEY feature originated in a previous version of the core. To maintain backwards compatibility, ASCIIKEY=$00 is the nonce that represents the empty queue. All callers, including those preferring the PETSCIIKEY interpretation, must test ASCIIKEY for $00 to know when the queue is empty.
There are possible typing events that have a translation in one of ASCII or PETSCII but not both. If an event has a PETSCII character but not an ASCII character, ASCIIKEY=$ff to distinguish between a non-ASCII event and an empty queue. $ff is a possible value in ASCII (umlaut-Y: Ÿ), so this is ambiguous. Any caller that needs to distinguish this case can test PETSCIIKEY for $59 when ASCIIKEY is $ff. This is not a backwards compatible behavior for previous callers that don’t know to disambiguate. The side effect of spurious Ÿ characters for 13 obscure typing events in previous ASCIIKEY callers was chosen as a tradeoff from designs that were more backwards compatible but would have caused other issues.
The modifier keys are presented separately to disambiguate cases that have the same ASCII or PETSCII code but are caused by different key combinations. In the screen editor, Ctrl-S has the same PETSCII code as Home, but has different behavior. We may eventually implement a raw key number view register that is completely unambiguous. For now, existing needs are well served by either ASCIIKEY or PETSCIIKEY.
There is only one typing event queue. When an event is dequeued, all views are updated simultaneously. Each typing event is only represented once for the entire system.
MODKEY $d60a[0:6] is not to be confused with $d611[0:6], which presents the current (immediate) state of the modifier keys independently of the typing event queue. The bit assignments are the same for both registers.
Example of polling for typing events indefinitely:
...
The getin
KERNAL routine processes the hardware typing event queue. Each time the KERNAL or a program tries to read a key via this routine, it reads from either 1) the active function key macro, 2) an internal buffer, or 3) the hardware typing event queue, in that order. When it reads from the hardware queue, it dequeues what it reads. The screen editor only calls getin
when it is waiting for input, unlike the keyboard IRQ routine which is called 50/60 times per second regardless of what program is running.
...
When the user presses Ctrl-S, it appears on the typing event queue.
getin
always skips Ctrl-S when it finds it in the queue, allowing the KERNAL IRQ routine to handle it via CIA lines as before. (This is functionally identical to previous ROM behavior:getin
never returns Ctrl-S.)Mega + Shift and No Scroll do not appear on the typing event queue when typed alone because they are modifier keys and not considered typing events. The keyboard IRQ can detect these key presses by testing $d611, which presents the immediate state of the modifier keys independently of typing events.
The keyboard IRQ routine is still accessible via the
key
routine atjsr $ffdf
. It is still worth calling from a program if the program replaces the KERNAL IRQ and wants to support Mega + Shift and No Scroll. The routine no longer populates a buffer, because this is handled in the core.The KERNAL still has an internal key buffer to support BASIC65 AUTO, and possibly future KERNAL features that wish to inject keystrokes into the input stream. (These variables are still undocumented for now.)
The KERNAL routine that scans for Run/Stop at
jsr $ffe1
is unaffected by this change. It still reads it from the CIA lines.The code that initiates a function key macro now lives in
getin
instead of the keyboard IRQ. This is an implementation detail that won’t be noticed by programs, because only the next call togetin
is affected by activating a function key macro.All other changes to the flow are internal to the KERNAL and screen editor. There is an internal screen editor subroutine jump table not documented for use by programs, and its API has changed.
The C65 ROM has a collection of extension vectors that are intended for use by programs but not yet documented. For example, once documented, a program can replace the vector that points to the KERNAL’s implementation of
getin
with another routine, typically one that calls the original getin routine along with some new extended behavior. None of these vectors are considered documented yet. The new ROM changes the extension vector APIs that Commodore intended for the keyboard IRQ. The MEGA65 project will document these vectors once we are confident that they work, are well designed, and won’t need to change again.