Merge branch 'master' into version_9

This commit is contained in:
Irmen de Jong 2023-05-15 22:43:03 +02:00
commit 05d152746f
2 changed files with 22 additions and 44 deletions

View File

@ -9,17 +9,16 @@ main {
sub start() { sub start() {
txt.print("ps2 custom key handler test - press keys! esc to quit!\n") txt.print("custom key handler test - press keys! esc to quit!\n")
sys.set_irqd() sys.set_irqd()
uword old_keyhdl = cx16.KEYHDL uword old_keyhdl = cx16.KEYHDL
cx16.KEYHDL = &keyboard_scancode_handler cx16.KEYHDL = &keyboard_scancode_handler
sys.clear_irqd() sys.clear_irqd()
bool escape_pressed while handle_keyboard_event() {
while not escape_pressed {
handle_keyboard_event()
} }
sys.set_irqd() sys.set_irqd()
cx16.KEYHDL = old_keyhdl cx16.KEYHDL = old_keyhdl
sys.clear_irqd() sys.clear_irqd()
@ -30,70 +29,49 @@ main {
; so that they won't get overwritten with initialization values every time. ; so that they won't get overwritten with initialization values every time.
; The assembly keyboard handler will set these, prog8 will read them. ; The assembly keyboard handler will set these, prog8 will read them.
bool @shared keyhdl_event ; is there a keyboard event to handle? bool @shared keyhdl_event ; is there a keyboard event to handle?
ubyte @shared keyhdl_prefix
ubyte @shared keyhdl_scancode ubyte @shared keyhdl_scancode
ubyte @shared keyhdl_updown
sub handle_keyboard_event() { sub handle_keyboard_event() -> bool {
; Potentially handle keyboard event. ; Potentially handle keyboard event.
; Note that we do this from the program's main loop instead of ; Note that we do this from the program's main loop instead of
; the actual keyboard handler routine itself. ; the actual keyboard handler routine itself.
; The reason for this is documented below in the handler assembly routine. ; The reason for this is documented below in the handler assembly routine.
if not keyhdl_event if not keyhdl_event
return return true
keyhdl_event = false keyhdl_event = false
txt.print_ubhex(keyhdl_prefix, true)
txt.chrout(':')
txt.print_ubhex(keyhdl_scancode, true) txt.print_ubhex(keyhdl_scancode, true)
txt.spc() txt.spc()
if keyhdl_updown if keyhdl_scancode & $80
txt.chrout('u') txt.chrout('u')
else else
txt.chrout('d') txt.chrout('d')
txt.nl() txt.nl()
if keyhdl_prefix==0 and keyhdl_scancode==119 and keyhdl_updown { return keyhdl_scancode!=$6e ; escape breaks the loop
; escape was pressed! exit back to basic
main.start.escape_pressed = true
}
} }
asmsub keyboard_scancode_handler() { asmsub keyboard_scancode_handler() {
; NOTE that the keyboard handler is an asm subroutine. ; NOTE that the keyboard handler is an asm subroutine.
; Unfortunately is it not possible to use prog8 code or calls here, ; Unfortunately is it not possible to use prog8 code or calls here,
; because the X register gets overwritten here (to store the prefix byte) ; because the X register gets overwritten here by the kernal.
; and prog8 uses the X register internally (for the evaluation stack). ; Pog8 uses the X register internally (for the software eval stack).
; So it is unsafe to call prog8 code from here because the evaluation stack pointer ; So it is unsafe to call prog8 code from here because the evaluation stack pointer
; will be invalid which produces undefined results. ; will be invalid which produces undefined results.
; So, instead, we store the various keyboard event bytes and signal ; So, instead, we store the various keyboard event bytes and signal
; the main prog8 program that a keyboard event has occurred. ; the main prog8 program that a keyboard event has occurred.
; It then processes it independently from the assembly code here. ; It then processes it independently from the assembly code here.
; ;
; Unfortunately this also means you cannot decide from that prog8 code ; Unfortunately this also means you cannot decide easily from that prog8 code
; if the keyboard press should be consumed/ignored or put into the keyboard queue ; 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) ; (this is controlled by returning 0 or 1 in register A here)
;
; see:
; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2002%20-%20Editor.md#custom-keyboard-scancode-handler
%asm {{ %asm {{
php
pha pha
phx
stz keyhdl_updown
bcc +
inc keyhdl_updown
+ stx keyhdl_prefix
sta keyhdl_scancode sta keyhdl_scancode
lda #1 lda #1
sta keyhdl_event sta keyhdl_event
; we can do additional stuff here and decide if we want to
; consume the key event or not (A=0 or A!=0)
plx
pla pla
lda #0 ;By setting A=0 we will remove this key event for now
tax lda #0 ; By setting A=0 we will eat this key event. leave A unchanged to pass it through.
plp
rts rts
}} }}
} }

View File

@ -1270,7 +1270,7 @@ class VirtualMachine(irProgram: IRProgram) {
else left / right else left / right
} }
"%" -> { "%" -> {
if(right==0.toUByte()) 0xffu if(right==0.toUByte()) 0u
else left % right else left % right
} }
else -> throw IllegalArgumentException("operator byte $operator") else -> throw IllegalArgumentException("operator byte $operator")
@ -1286,7 +1286,7 @@ class VirtualMachine(irProgram: IRProgram) {
else left / value else left / value
} }
"%" -> { "%" -> {
if(value==0.toUByte()) 0xffu if(value==0.toUByte()) 0u
else left % value else left % value
} }
else -> throw IllegalArgumentException("operator byte $operator") else -> throw IllegalArgumentException("operator byte $operator")
@ -1298,7 +1298,7 @@ class VirtualMachine(irProgram: IRProgram) {
val left = registers.getUB(reg1) val left = registers.getUB(reg1)
val right = registers.getUB(reg2) val right = registers.getUB(reg2)
val division = if(right==0.toUByte()) 0xffu else left / right val division = if(right==0.toUByte()) 0xffu else left / right
val remainder = if(right==0.toUByte()) 0xffu else left % right val remainder = if(right==0.toUByte()) 0u else left % right
valueStack.push(division.toUByte()) valueStack.push(division.toUByte())
valueStack.push(remainder.toUByte()) valueStack.push(remainder.toUByte())
} }
@ -1306,7 +1306,7 @@ class VirtualMachine(irProgram: IRProgram) {
private fun divAndModConstUByte(reg1: Int, value: UByte) { private fun divAndModConstUByte(reg1: Int, value: UByte) {
val left = registers.getUB(reg1) val left = registers.getUB(reg1)
val division = if(value==0.toUByte()) 0xffu else left / value val division = if(value==0.toUByte()) 0xffu else left / value
val remainder = if(value==0.toUByte()) 0xffu else left % value val remainder = if(value==0.toUByte()) 0u else left % value
valueStack.push(division.toUByte()) valueStack.push(division.toUByte())
valueStack.push(remainder.toUByte()) valueStack.push(remainder.toUByte())
} }
@ -1315,7 +1315,7 @@ class VirtualMachine(irProgram: IRProgram) {
val left = registers.getUW(reg1) val left = registers.getUW(reg1)
val right = registers.getUW(reg2) val right = registers.getUW(reg2)
val division = if(right==0.toUShort()) 0xffffu else left / right val division = if(right==0.toUShort()) 0xffffu else left / right
val remainder = if(right==0.toUShort()) 0xffffu else left % right val remainder = if(right==0.toUShort()) 0u else left % right
valueStack.pushw(division.toUShort()) valueStack.pushw(division.toUShort())
valueStack.pushw(remainder.toUShort()) valueStack.pushw(remainder.toUShort())
} }
@ -1323,7 +1323,7 @@ class VirtualMachine(irProgram: IRProgram) {
private fun divAndModConstUWord(reg1: Int, value: UShort) { private fun divAndModConstUWord(reg1: Int, value: UShort) {
val left = registers.getUW(reg1) val left = registers.getUW(reg1)
val division = if(value==0.toUShort()) 0xffffu else left / value val division = if(value==0.toUShort()) 0xffffu else left / value
val remainder = if(value==0.toUShort()) 0xffffu else left % value val remainder = if(value==0.toUShort()) 0u else left % value
valueStack.pushw(division.toUShort()) valueStack.pushw(division.toUShort())
valueStack.pushw(remainder.toUShort()) valueStack.pushw(remainder.toUShort())
} }
@ -1337,7 +1337,7 @@ class VirtualMachine(irProgram: IRProgram) {
else left / right else left / right
} }
"%" -> { "%" -> {
if(right==0.toUByte()) 0xffu if(right==0.toUByte()) 0u
else left % right else left % right
} }
else -> throw IllegalArgumentException("operator byte $operator") else -> throw IllegalArgumentException("operator byte $operator")
@ -1389,7 +1389,7 @@ class VirtualMachine(irProgram: IRProgram) {
else left / right else left / right
} }
"%" -> { "%" -> {
if(right==0.toUShort()) 0xffffu if(right==0.toUShort()) 0u
else left % right else left % right
} }
else -> throw IllegalArgumentException("operator word $operator") else -> throw IllegalArgumentException("operator word $operator")
@ -1405,7 +1405,7 @@ class VirtualMachine(irProgram: IRProgram) {
else left / value else left / value
} }
"%" -> { "%" -> {
if(value==0.toUShort()) 0xffffu if(value==0.toUShort()) 0u
else left % value else left % value
} }
else -> throw IllegalArgumentException("operator word $operator") else -> throw IllegalArgumentException("operator word $operator")
@ -1422,7 +1422,7 @@ class VirtualMachine(irProgram: IRProgram) {
else left / right else left / right
} }
"%" -> { "%" -> {
if(right==0.toUShort()) 0xffffu if(right==0.toUShort()) 0u
else left % right else left % right
} }
else -> throw IllegalArgumentException("operator word $operator") else -> throw IllegalArgumentException("operator word $operator")