2022-04-02 00:08:01 +00:00
|
|
|
%import textio
|
|
|
|
%zeropage basicsafe
|
|
|
|
%option no_sysinit
|
|
|
|
|
2023-05-14 21:29:04 +00:00
|
|
|
; The documentation for custom PS2 key handlers can be found here:
|
2023-03-12 15:09:55 +00:00
|
|
|
; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2002%20-%20Editor.md#custom-keyboard-scancode-handler
|
|
|
|
|
2022-04-02 00:08:01 +00:00
|
|
|
main {
|
|
|
|
|
|
|
|
sub start() {
|
|
|
|
|
2023-05-14 21:33:57 +00:00
|
|
|
txt.print("custom key handler test - press keys! esc to quit!\n")
|
2022-04-02 00:08:01 +00:00
|
|
|
|
|
|
|
sys.set_irqd()
|
|
|
|
uword old_keyhdl = cx16.KEYHDL
|
2023-05-14 21:29:04 +00:00
|
|
|
cx16.KEYHDL = &keyboard_scancode_handler
|
2022-04-02 00:08:01 +00:00
|
|
|
sys.clear_irqd()
|
|
|
|
|
2023-05-14 21:33:57 +00:00
|
|
|
while handle_keyboard_event() {
|
2022-04-02 00:08:01 +00:00
|
|
|
}
|
2023-05-14 21:33:57 +00:00
|
|
|
|
2022-04-02 00:08:01 +00:00
|
|
|
sys.set_irqd()
|
|
|
|
cx16.KEYHDL = old_keyhdl
|
|
|
|
sys.clear_irqd()
|
|
|
|
}
|
|
|
|
|
2023-05-14 21:29:04 +00:00
|
|
|
; Keyboard handler communication variables.
|
|
|
|
; these need to be in block scope instead of in a subroutine,
|
|
|
|
; so that they won't get overwritten with initialization values every time.
|
|
|
|
; The assembly keyboard handler will set these, prog8 will read them.
|
|
|
|
bool @shared keyhdl_event ; is there a keyboard event to handle?
|
|
|
|
ubyte @shared keyhdl_scancode
|
|
|
|
|
2023-05-14 21:33:57 +00:00
|
|
|
sub handle_keyboard_event() -> bool {
|
2023-05-14 21:29:04 +00:00
|
|
|
; Potentially handle keyboard event.
|
|
|
|
; Note that we do this from the program's main loop instead of
|
|
|
|
; the actual keyboard handler routine itself.
|
|
|
|
; The reason for this is documented below in the handler assembly routine.
|
|
|
|
if not keyhdl_event
|
2023-05-14 21:33:57 +00:00
|
|
|
return true
|
2023-05-14 21:29:04 +00:00
|
|
|
keyhdl_event = false
|
|
|
|
txt.print_ubhex(keyhdl_scancode, true)
|
2022-04-02 00:08:01 +00:00
|
|
|
txt.spc()
|
2023-05-14 21:33:57 +00:00
|
|
|
if keyhdl_scancode & $80
|
2022-04-02 00:08:01 +00:00
|
|
|
txt.chrout('u')
|
|
|
|
else
|
|
|
|
txt.chrout('d')
|
|
|
|
txt.nl()
|
2023-05-14 21:33:57 +00:00
|
|
|
return keyhdl_scancode!=$6e ; escape breaks the loop
|
2023-01-24 00:30:57 +00:00
|
|
|
}
|
|
|
|
|
2023-05-14 21:29:04 +00:00
|
|
|
asmsub keyboard_scancode_handler() {
|
|
|
|
; NOTE that the keyboard handler is an asm subroutine.
|
|
|
|
; Unfortunately is it not possible to use prog8 code or calls here,
|
2023-05-14 21:33:57 +00:00
|
|
|
; because the X register gets overwritten here by the kernal.
|
|
|
|
; Pog8 uses the X register internally (for the software eval stack).
|
2023-05-14 21:29:04 +00:00
|
|
|
; So it is unsafe to call prog8 code from here because the evaluation stack pointer
|
|
|
|
; will be invalid which produces undefined results.
|
|
|
|
; So, instead, we store the various keyboard event bytes and signal
|
|
|
|
; the main prog8 program that a keyboard event has occurred.
|
|
|
|
; It then processes it independently from the assembly code here.
|
|
|
|
;
|
2023-05-14 21:33:57 +00:00
|
|
|
; Unfortunately this also means you cannot decide easily from that prog8 code
|
2023-05-14 21:29:04 +00:00
|
|
|
; if the keyboard press should be consumed/ignored or put into the keyboard queue
|
|
|
|
; (this is controlled by returning 0 or 1 in register A here)
|
|
|
|
|
|
|
|
%asm {{
|
|
|
|
pha
|
2023-07-02 17:38:44 +00:00
|
|
|
sta p8_keyhdl_scancode
|
2023-05-14 21:29:04 +00:00
|
|
|
lda #1
|
2023-07-02 17:38:44 +00:00
|
|
|
sta p8_keyhdl_event
|
2023-05-14 21:29:04 +00:00
|
|
|
pla
|
2023-05-14 21:33:57 +00:00
|
|
|
|
2023-07-02 17:38:44 +00:00
|
|
|
lda #0 ; By setting A=0 we will eat this key event. leave A unchanged to pass it through.
|
2023-05-14 21:29:04 +00:00
|
|
|
rts
|
|
|
|
}}
|
|
|
|
}
|
2022-04-02 00:08:01 +00:00
|
|
|
}
|