diff --git a/src/aliases/,aliases_ram_lowmem_m65.s b/src/aliases/,aliases_ram_lowmem_m65.s index af7d83bb..5a683453 100644 --- a/src/aliases/,aliases_ram_lowmem_m65.s +++ b/src/aliases/,aliases_ram_lowmem_m65.s @@ -58,7 +58,9 @@ !addr M65_KB_COLSUM = $59F ; sum (OR) of the M65_KB_COLSCAN !addr M65_KB_PRESSED = $560 ; $560-$562 keys pressed, used during scanning keyboard !addr M65_KB_PRESSED_OLD = $563 ; $563-$565 keys pressed during previous scan - ; $560-$5EB -- UNUSED -- + !addr M65_KB_PRESSED_NEW = $566 ; $566-$568 set of M65_KB_PRESSED minus M65_KB_PRESSED_OLD + !addr M65_JOYCRSR = $569 ; joystick to be used for cursor movement + ; $56A-$5EB -- UNUSED -- !addr M65_DMAGIC_LIST = $5F1 ; $5EF-$5FF reserved for DMAgic list, 15 bytes (modulo bytes are not needed) !addr M65_RS232_INBUF = $600 ; $600-$6FF -- reserved for RS-232 input buffer -- !addr M65_RS232_OUTBUF = $700 ; $700-$7FF -- reserved for RS-232 output buffer -- diff --git a/src/kernal/board_m65/mega65_native_meminit.s b/src/kernal/board_m65/mega65_native_meminit.s index 781f2897..b35c0b27 100644 --- a/src/kernal/board_m65/mega65_native_meminit.s +++ b/src/kernal/board_m65/mega65_native_meminit.s @@ -4,6 +4,18 @@ m65_native_meminit: + ; Clear pages 4-7 + + lda #$00 + tax +@1: + sta $0400, x + sta $0500, x + sta $0600, x + sta $0700, x + inx + bne @1 + ; Initialize variables for keyboard scanning jsr m65_scnkey_init_pressed diff --git a/src/kernal/keyboard_m65/mega65_scnkey.s b/src/kernal/keyboard_m65/mega65_scnkey.s index 6527a9fb..06c560f2 100644 --- a/src/kernal/keyboard_m65/mega65_scnkey.s +++ b/src/kernal/keyboard_m65/mega65_scnkey.s @@ -21,8 +21,8 @@ m65_scnkey: m65_scnkey_fetch_loop: - stx $D614 - lda $D613 + stx KBSCN_SELECT + lda KBSCN_PEEK eor #$FF ; let bit 1 mean 'pressed', not the otherwise sta M65_KB_COLSCAN, x ora M65_KB_COLSUM @@ -37,7 +37,7 @@ m65_scnkey_fetch_loop: lda SHFLAG sta LSTSHF ; needed for SHIFT+VENDOR support - ldx #$00 + inx ; .X goes from $FF to $00 stx SHFLAG lda M65_KB_BUCKY @@ -80,17 +80,17 @@ m65_scnkey_keytab_set_done: ; Scan the keyboard matrix stored in memory to determine which keys were pressed ; - ldx #$02 -@1: - lda M65_KB_PRESSED, x - sta M65_KB_PRESSED_OLD, x - dex - bpl @1 + lda M65_KB_PRESSED+0 + sta M65_KB_PRESSED_OLD+0 + lda M65_KB_PRESSED+1 + sta M65_KB_PRESSED_OLD+1 + lda M65_KB_PRESSED+2 + sta M65_KB_PRESSED_OLD+2 jsr m65_scnkey_init_pressed lda M65_KB_COLSUM - beq m65_scnkey_no_keys ; branch if no key was pressed XXX try joystick + beq m65_scnkey_try_joystick ; branch if no key was pressed ldx #$08 @@ -117,7 +117,7 @@ m65_scnkey_loop_2: ; Found a pressed key - add it to the list lda M65_KB_PRESSED+2 - bpl m65_scnkey_jam ; branch if too many keys pressed + +bpl m65_scnkey_pla_jam ; branch if too many keys pressed lda M65_KB_PRESSED+1 sta M65_KB_PRESSED+2 lda M65_KB_PRESSED+0 @@ -142,24 +142,79 @@ m65_scnkey_next_1: ; Analyze currently and previously pressed keys ; - ; XXX add proper implementation - ldy M65_KB_PRESSED+0 + ; First select the new keys + lda M65_KB_PRESSED+0 + jsr m65_scnkey_compare_with_old + jsr m65_scnkey_add_if_new_valid + lda M65_KB_PRESSED+1 + jsr m65_scnkey_compare_with_old + jsr m65_scnkey_add_if_new_valid + lda M65_KB_PRESSED+2 + jsr m65_scnkey_compare_with_old + jsr m65_scnkey_add_if_new_valid + ; If we have more than one key - consider it jam + lda M65_KB_PRESSED_NEW+1 + bmi m65_scnkey_jam + ; If we have exactly one new key - this is our key + ldy M65_KB_PRESSED_NEW+0 + bpl m65_scnkey_got_key + + ; No new key - check if the last one is still pressed + + ldy LSTX + cmp M65_KB_PRESSED+0 + beq m65_scnkey_got_key_skip_cmp + cmp M65_KB_PRESSED+1 + beq m65_scnkey_got_key_skip_cmp + cmp M65_KB_PRESSED+2 + beq m65_scnkey_got_key_skip_cmp + + ; Nope, previous key is not pressed ; FALLTROUGH +m65_scnkey_try_joystick: + + lda M65_JOYCRSR + cmp #$02 + beq m65_scnkey_try_joy2 + cmp #$01 + bne m65_scnkey_no_keys + + ; FALLTROUGH + +m65_scnkey_try_joy1: + + +nop + ; XXX provide implementation + +m65_scnkey_try_joy2: + + +nop + ; XXX provide implementation + +m65_scnkey_try_joy_common: + + ; XXX provide implementation + bra m65_scnkey_no_keys + m65_scnkey_got_key: ; .Y should now contain the key offset in matrix pointed by KEYTAB cpy LSTX beq m65_scnkey_try_repeat ; branch if the same key as previously sty LSTX + ; FALLTROUGH + +m65_scnkey_got_key_skip_cmp: + ; Reset key repeat counters lda #CONFIG_KEY_DELAY @@ -187,7 +242,7 @@ m65_scnkey_output_key: ; Check if KEYTAB is valid lda KEYTAB+1 - beq m65_scnkey_jam + beq m65_scnkey_no_keys ; Retrieve the PETSCII code @@ -210,9 +265,14 @@ m65_scnkey_done: rts -m65_scnkey_jam: +m65_scnkey_pla_jam: pla + + ; FALLTROUGH + +m65_scnkey_jam: + jsr m65_scnkey_init_pressed ; FALLTROUGH @@ -264,3 +324,45 @@ m65_scnkey_handle_repeat: dec KOUNT rts + + + +m65_scnkey_compare_with_old: + + ; Compare key index with the ones from previous scan + + cmp M65_KB_PRESSED+0 + beq @1 + cmp M65_KB_PRESSED+1 + beq @1 + cmp M65_KB_PRESSED+2 +@1: + rts + +m65_scnkey_add_if_new_valid: + + beq @1 + cmp #$FF ; invalid key code + beq @1 + + ; XXX filter-out SHIFT, VENDOR, etc. + ;cmp $xx ; left SHIFT + ;beq @1 + ;cmp $xx ; right SHIFT + ;beq @1 + ;cmp $xx ; VENDOR + ;beq @1 + ;cmp $xx ; CAPS LOCK + ;beq @1 + ;cmp $xx ; ALT + ;beq @1 + + ; New, valid key index + + ldx M65_KB_PRESSED_NEW+1 + stx M65_KB_PRESSED_NEW+2 + ldx M65_KB_PRESSED_NEW+0 + stx M65_KB_PRESSED_NEW+1 + sta M65_KB_PRESSED_NEW+0 +@1 + rts diff --git a/src/kernal/keyboard_m65/mega65_scnkey_init_pressed.s b/src/kernal/keyboard_m65/mega65_scnkey_init_pressed.s index 35e2761d..619ea52b 100644 --- a/src/kernal/keyboard_m65/mega65_scnkey_init_pressed.s +++ b/src/kernal/keyboard_m65/mega65_scnkey_init_pressed.s @@ -8,5 +8,8 @@ m65_scnkey_init_pressed: sta M65_KB_PRESSED+0 sta M65_KB_PRESSED+1 sta M65_KB_PRESSED+2 + sta M65_KB_PRESSED_NEW+0 + sta M65_KB_PRESSED_NEW+1 + sta M65_KB_PRESSED_NEW+2 rts