more sane directory name, updated binaries

This commit is contained in:
FeralChild64 committed 2020-06-26 19:44:01 +02:00
1 parent d4d32095d1
commit 76aaf298b8
697 files changed
+56 -56

No files matched your search

+184
View File
@@ -0,0 +1,184 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Keyboard part of the CHRIN routine
//
chrin_keyboard:
// Save .X
stx XSAV
// Save .Y
phy_trash_a
chrin_repeat:
// Do we have a line of input we are currently returning?
// If so, return the next byte, and clear the flag when we reach the end.
// Do we have a line of input waiting?
lda CRSW
beq read_from_keyboard
// Yes, we have input waiting at (LSXP)+CRSW
// When CRSW = INDX, then we return a carriage return
// and clear the flag
cmp INDX
bne not_end_of_input
// Return carriage return and clear pending input and quote flags
lda #$00
sta CRSW
sta QTSW
// FALLTROUGH
empty_line:
// For an empty line, just return the carriage return
// (and do not forget to actually print the carriage return, so that
// the cursor advances and screen scrolls as required)
ply_trash_a
ldx XSAV
clc
lda #$0d
rts
not_end_of_input:
// Advance index
inc CRSW
// Return next byte of waiting
tay
chrin_keyboard_return_byte:
lda (LSXP),y
jsr screen_check_toggle_quote
tax
ply_trash_a
txa
ldx XSAV
jsr screen_code_to_petscii
clc
rts
read_from_keyboard:
jsr cursor_enable
// Wait for a key
lda NDX
beq chrin_repeat
lda KEYD
cmp #$0D
bne not_enter
chrin_enter:
jsr cursor_disable
jsr pop_keyboard_buffer
jsr cursor_hide_if_visible
// It was enter.
// Note that we have a line of input to return, and return the first byte thereof
// after computing and storing its length.
// (Computes Mapping the 64, p96)
// Set pointer to line of input
lda PNT+0
sta LSXP+0
lda PNT+1
sta LSXP+1
// If the current line is a continuation of the previous one, decrease LSXP by 40
ldy TBLX
lda LDTB1, y
bmi chrin_enter_calc_length // branch if not continuation
lda LSXP+0
sec
sbc #40
sta LSXP+0
bcs !+
dec LSXP+1
!:
ldy #80
bne chrin_enter_loop // branch always
chrin_enter_calc_length:
// Calculate length
jsr screen_get_logical_line_end_ptr
iny
chrin_enter_loop:
// Retrieve bytes
dey
bmi empty_line
lda (LSXP),y
cmp #$20
beq chrin_enter_loop
iny
sty INDX
// Set mark informing that we are returning a line
ldy #$01
sty CRSW
// Clear quote mode mark
dey // set .Y to 0
sty QTSW
// Return first char of line
beq chrin_keyboard_return_byte // branch always
not_enter:
lda KEYD
#if CONFIG_PROGRAMMABLE_KEYS
ldx #(__programmable_keys_codes_end - programmable_keys_codes - 1)
chrin_programmable_loop:
cmp programmable_keys_codes, x
beq chrin_programmable_key
dex
bpl chrin_programmable_loop
// FALLTROUGH
#endif // CONFIG_PROGRAMMABLE_KEYS
chrin_print_character:
jsr CHROUT
jsr pop_keyboard_buffer
// Keep looking for input from keyboard until carriage return
jmp chrin_repeat
#if CONFIG_PROGRAMMABLE_KEYS
chrin_programmable_key:
// .X contains index of the key code, we need offset to key string instead
lda programmable_keys_offsets, x
tax
// Print all the characters assigned to key
!:
lda programmable_keys_strings, x
beq chrin_enter
jsr CHROUT // our implementation preserves .X too
inx
bne !- // jumps always
#endif // CONFIG_PROGRAMMABLE_KEYS
+33
View File
@@ -0,0 +1,33 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Well-known Kernal routine, described in:
//
// - http://sta.c64.org/cbm64kbdfunc.html
//
getin_keyboard: // XXX confirm that here is really a part of GETIN!
// Check for a key
lda NDX
bne !+
// Nothing in keyboard buffer to read
sec
rts
!:
lda KEYD
pha
phy_trash_a
jsr pop_keyboard_buffer
ply_trash_a
pla
clc
rts
+4
View File
@@ -0,0 +1,4 @@
$F142 is a well-known address of keyboard reading routine, described for example here:
- http://sta.c64.org/cbm64kbdfunc.html
It is used for eexample by a music eeditor here: https://github.com/martinpiper/C64Public/blob/master/MusicEditor/GetKey.a
+31
View File
@@ -0,0 +1,31 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmers Reference Guide - page 301
// - [CM64] Computes Mapping the Commodore 64 - page 232
//
// CPU registers that has to be preserved (see [RG64]): .Y
//
STOP:
// Bit 7 of STKEY contains the state of the STOP key
// (Computes Mapping the 64, p27)
// BASIC checks carry flag to indicate STOP or not
lda STKEY
bpl stop_pressed
// By trial and error, we know that Z + C = BREAK
// and that neither should be set otherwise
lda #$FF
clc
rts
stop_pressed:
sec
lda #$00
rts
+64
View File
@@ -0,0 +1,64 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Keyboard matrix, based on
//
// - [RG64] C64 Programmers Reference Guide - pages 379-381
// - [CM64] Computes Mapping the Commodore 64 - pages 38-39
// - http://commodore128.mirkosoft.sk/keyboard.html (C128 extension)
// - http://www.zimmers.net/cbmpics/cbm/c65/c65manual.txt
// Values can be computed by running a program like:
// 10 GET A$ : IF A$ = "" GOTO10
// 20 PRINT ASC(A$) : GOTO10
// and converting the values
kb_matrix:
__kb_matrix_normal:
.byte $14,$0D,$1D,$88,$85,$86,$87,$11
.byte $33,$57,$41,$34,$5A,$53,$45,$00
.byte $35,$52,$44,$36,$43,$46,$54,$58
.byte $37,$59,$47,$38,$42,$48,$55,$56
.byte $39,$49,$4A,$30,$4D,$4B,$4F,$4E
.byte $2B,$50,$4C,$2D,$2E,$3A,$40,$2C
.byte $5C,$2A,$3B,$13,$00,$3D,$5E,$2F
.byte $31,$5F,$00,$32,$20,$00,$51,$03
__kb_matrix_shift:
.byte $94,$8D,$9D,$8C,$89,$8A,$8B,$91
.byte $23,$77,$61,$24,$7A,$73,$65,$00
.byte $25,$72,$64,$26,$63,$66,$74,$78
.byte $27,$79,$67,$28,$62,$68,$75,$76
.byte $29,$69,$6A,$92,$6D,$6B,$6F,$6E
.byte $DB,$70,$6C,$DD,$3E,$5B,$BA,$3C
.byte $A9,$C0,$5D,$93,$00,$3D,$DE,$3F
.byte $21,$5F,$00,$22,$A0,$00,$71,$83
__kb_matrix_vendor:
.byte $94,$8D,$9D,$8C,$89,$8A,$8B,$91
.byte $96,$B3,$B0,$97,$AD,$AE,$B1,$00
.byte $98,$B2,$AC,$99,$BC,$BB,$A3,$BD
.byte $9A,$B7,$A5,$9B,$BF,$B4,$B8,$BE
.byte $30,$A2,$B5,$30,$A7,$A1,$B9,$AA
.byte $A6,$AF,$B6,$DC,$3E,$5B,$A4,$3C
.byte $A8,$DF,$5D,$93,$00,$3D,$DE,$3F
.byte $81,$5F,$00,$95,$a0,$00,$AB,$83
__kb_matrix_ctrl:
.byte $00,$00,$00,$00,$00,$00,$00,$00
.byte $1C,$17,$01,$9F,$1A,$13,$05,$00
.byte $9C,$12,$04,$1E,$03,$06,$14,$18
.byte $1F,$19,$07,$9E,$02,$08,$15,$16
.byte $12,$09,$0A,$92,$0D,$0B,$0F,$0E
#if CONFIG_EDIT_TABULATORS
.byte $00,$10,$0C,$00,KEY_TAB_FW,$1B,$00,KEY_TAB_BW
#else
.byte $00,$10,$0C,$00,$00,$1B,$00,$00
#endif
.byte $1C,$00,$1D,$00,$00,$1F,$1E,$00
.byte $90,$06,$00,$05,$00,$00,$11,$00
+34
View File
@@ -0,0 +1,34 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Extended keyboard matrix for Commodore 128 keyboards, based on
//
// - [CM128] Computes Mapping the Commodore 128 - page 290
// - http://commodore128.mirkosoft.sk/keyboard.html
//
#if CONFIG_KEYBOARD_C128 && !CONFIG_LEGACY_SCNKEY
kb_matrix_128:
.byte KEY_HELP,$38,$35,KEY_TAB_FW,$32,$34,$37,$31
.byte KEY_ESC,$2B,$2D,$8D,$0D,$36,$39,$33
.byte $00,$30,$2E,$91,$11,$9D,$1D,$00
kb_matrix_128_bucky_filter:
// values for OR with CIA1_PRB content to filter out bucky keys
.byte %00000000
.byte %00000000
.byte %10000001 // ALT, NO_SCRL
#endif // CONFIG_KEYBOARD_C128 and no CONFIG_LEGACY_SCNKEY
+25
View File
@@ -0,0 +1,25 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Extended keyboard matrix for Commodore 65 keyboards, based on
//
// - https://github.com/MEGA65/c65-specifications/blob/master/c65manualupdated.txt
//
#if CONFIG_KEYBOARD_C65 && !CONFIG_LEGACY_SCNKEY
kb_matrix_65:
.byte $00, KEY_TAB_FW, $00, KEY_HELP, KEY_F9, KEY_F11, KEY_F13, KEY_ESC
kb_matrix_65_shifted:
.byte $00, KEY_TAB_BW, $00, KEY_HELP, KEY_F10, KEY_F12, KEY_F14, KEY_ESC
#endif // CONFIG_KEYBOARD_C65 and no CONFIG_LEGACY_SCNKEY
@@ -0,0 +1,27 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Matrix ids of keys which should be repeated regardless of RPTFLG
//
// Values based on:
// - [CM64] Computes Mapping the Commodore 64 - page 58
//
#if !CONFIG_LEGACY_SCNKEY && !CONFIG_KEY_REPEAT_ALWAYS
kb_matrix_alwaysrepeat:
.byte $3C // SPACE
.byte $02 // CRSR LEFT/RIGHT
.byte $07 // CRSR UP/DOWN
.byte $00 // INS/DEL
__kb_matrix_alwaysrepeat_end:
#endif // no CONFIG_LEGACY_SCNKEY and no CONFIG_KEY_REPEAT_ALWAYS
+89
View File
@@ -0,0 +1,89 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Matrix for retrieving bucky key status on the C64 keyboard
//
// Values based on:
// - [CM64] Computes Mapping the Commodore 64 - pages 58 (SHFLAG), 173 (matrix)
// - [CM128] Computes Mapping the Commodore 128 - pages 212 (SHFLAG), 290 (matrix)
// - https://github.com/MEGA65/c65-specifications/blob/master/c65manualupdated.txt
//
#if !CONFIG_LEGACY_SCNKEY
kb_matrix_bucky_confmask: // values to be written to CIA1_PRA
.byte %11111101 // SHIFT (left)
.byte %10111111 // SHIFT (right)
.byte %01111111 // VENDOR
.byte %01111111 // CTRL
#if CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C65
.byte %11111111 // C128 / C65 extra keys
.byte %11111111
#endif
__kb_matrix_bucky_confmask_end:
#if CONFIG_KEYBOARD_C128
kb_matrix_bucky_confmask_c128: // values to be written to VIC_XSCAN
.byte %11111111
.byte %11111111
.byte %11111111
.byte %11111111
.byte %11111011 // ALT
.byte %11111011 // NO_SCRL
#endif
#if CONFIG_KEYBOARD_C65
kb_matrix_bucky_confmask_c65: // values to be written to C65_EXTKEYS_PR
.byte %11111111
.byte %11111111
.byte %11111111
.byte %11111111
.byte %11111101 // ALT
.byte %11111101 // NO_SCRL
#endif
kb_matrix_bucky_testmask: // for AND with CIA1_PRB value
.byte %10000000 // SHIFT (left)
.byte %00010000 // SHIFT (right)
.byte %00100000 // VENDOR
.byte %00000100 // CTRL
#if CONFIG_KEYBOARD_C128
.byte %10000000 // ALT
.byte %00000001 // NO_SCRL
#endif
#if CONFIG_KEYBOARD_C65
.byte %00000100 // ALT
.byte %00000001 // NO_SCRL
#endif
kb_matrix_bucky_shflag: // mask to be ORed to SHFLAG to mark key status
.byte KEY_FLAG_SHIFT
.byte KEY_FLAG_SHIFT
.byte KEY_FLAG_VENDOR
.byte KEY_FLAG_CTRL
#if CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C65
.byte KEY_FLAG_ALT
.byte KEY_FLAG_NO_SCRL
#endif
#endif // no CONFIG_LEGACY_SCNKEY
@@ -0,0 +1,31 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Matrix for filtering out bucky keys while scanning the C64 keyboard
//
// Values based on:
// - [CM64] Computes Mapping the Commodore 64 - pags 58 (SHFLAG), 173 (matrix)
//
#if !CONFIG_LEGACY_SCNKEY
kb_matrix_bucky_filter:
// values for OR with CIA1_PRB content to filter out bucky keys
.byte %00000000
.byte %10000000 // SHIFT (left)
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00000000
.byte %00010000 // SHIFT (right)
.byte %00100100 // VENDOR + CONTROL
#endif // no CONFIG_LEGACY_SCNKEY
+42
View File
@@ -0,0 +1,42 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Matrix for retrieving C64 joystick status and inject is as keyboard event
//
#if !CONFIG_LEGACY_SCNKEY && (CONFIG_JOY1_CURSOR || CONFIG_JOY2_CURSOR)
kb_matrix_joy_status:
.byte %00001110 // up
.byte %00001101 // down
.byte %00001011 // left
.byte %00000111 // right
kb_matrix_joy_keytab_idx:
.byte $07 // up
.byte $07 // down
.byte $02 // left
.byte $02 // right
kb_matrix_joy_keytab_lo:
.byte <__kb_matrix_shift // up
.byte <__kb_matrix_normal // down
.byte <__kb_matrix_shift // left
.byte <__kb_matrix_normal // right
kb_matrix_joy_keytab_hi:
.byte >__kb_matrix_shift // up
.byte >__kb_matrix_normal // down
.byte >__kb_matrix_shift // left
.byte >__kb_matrix_normal // right
#endif
+27
View File
@@ -0,0 +1,27 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Helper table for determining keyboard matrix decoding table on the C64 keyboard
//
// When more than one bucky keey is pressed, decoding keys is asking for trouble,
// so never allow this.
//
#if !CONFIG_LEGACY_SCNKEY
kb_matrix_lookup:
.byte (__kb_matrix_normal - kb_matrix) // %000 Normal
.byte (__kb_matrix_shift - kb_matrix) // %001 SHIFT
.byte (__kb_matrix_vendor - kb_matrix) // %010 VENDOR
.byte $FF // %011 SHIFT+VENDOR
.byte (__kb_matrix_ctrl - kb_matrix) // %100 CTRL
.byte $FF // %101 SHIFT+CTRL
.byte $FF // %110 VENDOR+CTRL
.byte $FF // %111 SHIFT+VENDOR+CTRL
#endif
@@ -0,0 +1,32 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Work out if normal, shifted, control or Vendor modified keyboard.
// Table contains the offsets into keyboard_matrixes that should be used
// for different values of the bottom 3 bits of key_bucky_state XXX
// Interaction is simple to work out when playing with a C64:
// CTRL trumps SHIFT or VENDOR
// VENDOR + SHIFT = DOES NOTHING
// All 3 does CONTROL
//
// This lookup table is used by TWW/CTR keyboard routine only!
#if CONFIG_LEGACY_SCNKEY
kb_matrix_lookup:
.byte $00 // Normal
.byte $40 // Shifted
.byte $80 // Control
.byte $80 // Control + SHIFT
.byte $C0 // Vendor
.byte $C0 // Vendor + SHIFT
.byte $80 // Vendor + CTRL
.byte $80 // Vendor + CTRL + SHIFT
#endif // CONFIG_LEGACY_SCNKEY
+33
View File
@@ -0,0 +1,33 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Single row key codes for scanning the C64 keyboard
//
// Values based on:
// - [CM64] Computes Mapping the Commodore 64 - pags 58 (SHFLAG), 173 (matrix)
//
#if !CONFIG_LEGACY_SCNKEY
kb_matrix_row_keys:
// - values for CIA1_PRA to connect only the given row
// - first 3 values also meant for VIC_XSCAN for C128 keyboards
// - also used to scan a single row
.byte %11111110
.byte %11111101
.byte %11111011
.byte %11110111
.byte %11101111
.byte %11011111
.byte %10111111
.byte %01111111
#endif // no CONFIG_LEGACY_SCNKEY
@@ -0,0 +1,27 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Helper values to quickly determine row offset from the start of keyboard matrix
//
#if !CONFIG_LEGACY_SCNKEY
kb_matrix_row_offsets:
// - offsets (in bytes) to the first bytes of keyboard matrix rows
.byte 0*8
.byte 1*8
.byte 2*8
.byte 3*8
.byte 4*8
.byte 5*8
.byte 6*8
.byte 7*8
#endif // no CONFIG_LEGACY_SCNKEY
+26
View File
@@ -0,0 +1,26 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Helper routine - disconnects the keyboard from CIA1_PRB,
// leaves $FF in .X (behavior needed in some places)
//
#if !CONFIG_LEGACY_SCNKEY
keyboard_disconnect:
ldx #$FF
stx CIA1_PRA // disconnect all the rows
#if CONFIG_KEYBOARD_C128
stx VIC_XSCAN
#endif
rts
#endif
+490
View File
@@ -0,0 +1,490 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmers Reference Guide - page 295
// - [CM64] Computes Mapping the Commodore 64 - page 220
//
// CPU registers that has to be preserved (see [RG64]): none
//
// Variables used:
// - KEYTAB - keyboard matrix pointer
// - DELAY - counter for first delay between key repeats
// - KOUNT - counter for next delays between key repeats
// - SHFLAG - SHIFT / CTRL / VENDOR keypress status
// - NDX - number of characters in keyboard buffer
// - XMAX - maximum size of keyboard buffer
// - LSTX - matrix coordinate of last pressed key
// - LSTSHF - previous status of SHFLAG
// - MODE - flag, whether charset toggle (SHIFT+VENDOR) is allowed
// - RPTFLG - whether key repeat is allowed
#if !CONFIG_LEGACY_SCNKEY
// Routine takes some ideas from TWW/CTR proposal, see here:
// - http://codebase64.org/doku.php?id=base:scanning_the_keyboard_the_correct_and_non_kernal_way
SCNKEY:
#if CONFIG_KEYBOARD_C65 && CONFIG_MB_MEGA_65
// Idea by Paul Gardner-Stephen
lda VIC_XPOS // check raster X position
cmp VIC_XPOS // if it changes, we are on a MEGA65 with VIC-IV registers already visible
bne scnkey_viciv_mode
// We are on machine that is not in VIC-IV IO mode, so try enabling it (harmless on C64/C65)
// If we are on a C65 (or MEGA65 with C65 VIC-III IO mode selected), the above test would
// have failed, but we could already be in C65 IO mode. In that case, this will disable C65 IO
// mode when done. This is not ideal, but as MEGA65s start C65 mode with VIC-IV IO mode
// selected anyway, it should not be a big problem in practice.
jsr mega65_unhide
jsr scnkey_viciv_mode
sta VIC_KEY // hide Mega65 registers
rts
scnkey_viciv_mode:
#endif
// Prepare for SHFLAG update
lda SHFLAG
sta LSTSHF
lda #$00
sta SHFLAG
#if !CONFIG_JOY2_CURSOR && CONFIG_KEY_FAST_SCAN
// Check for any activity - speed optimization, but cannot be done
// that early if we are to scan the joystick #2
ldx #$00
stx CIA1_PRA // connect all the rows
#if CONFIG_KEYBOARD_C128
stx VIC_XSCAN
#endif
dex // puts $FF
cpx CIA1_PRB
beq scnkey_no_keys
#endif
// Retrieve SHIFT / VENDOR / CTRL / ALT / CAPS LOCK status
#if CONFIG_KEYBOARD_C128_CAPS_LOCK
// First check if this is really a C128 - to avoid false positive
ldx #$00
stx VIC_XSCAN
dex // puts $FF
cpx VIC_XSCAN
beq !+ // branch if C64, C128 will keep some bits cleared
lda CPU_R6510
and #$40
bne !+ // branch if no CAPS LOCK
lda #KEY_CAPS_LOCK
sta SHFLAG
!:
#if !CONFIG_KEYBOARD_C128
stx VIC_XSCAN // disconnect C128 keys if no C128 keyboard is supported
#endif
#endif
#if CONFIG_KEYBOARD_C65_CAPS_LOCK
lda C65_EXTKEYS_PR
and #$01
bne !+ // branch if no CAPS LOCK
lda #KEY_CAPS_LOCK
sta SHFLAG
!:
#if !CONFIG_KEYBOARD_C65
ldx #$FF
stx C65_EXTKEYS_PR // disconnect C128 keys if no C128 keyboard is supported
#endif
#endif
ldy #(__kb_matrix_bucky_confmask_end - kb_matrix_bucky_confmask - 1)
scnkey_bucky_loop:
lda kb_matrix_bucky_confmask, y
sta CIA1_PRA
#if CONFIG_KEYBOARD_C128
lda kb_matrix_bucky_confmask_c128, y
sta VIC_XSCAN
#endif
#if CONFIG_KEYBOARD_C65
lda kb_matrix_bucky_confmask_c65, y
sta C65_EXTKEYS_PR
#endif
lda kb_matrix_bucky_testmask, y
and CIA1_PRB
bne !+ // branch if not pressed
lda SHFLAG
ora kb_matrix_bucky_shflag, y
sta SHFLAG
!:
dey
bpl scnkey_bucky_loop
// Set KEYTAB vector
jsr via_keylog // XXX for some CPUs we have indirect jsr
#if CONFIG_JOY2_CURSOR
// Check for control port 2 activity
ldx #$00
stx CIA1_DDRA // set port to input to read joystick
lda CIA1_PRA // read the joystick 2 status
dex // puts $FF
stx CIA1_DDRA // set port back to output
and #%00001111 // filter out anything but joystick movement
cmp #%00001111
bne scnkey_joystick_filtered
#if CONFIG_KEY_FAST_SCAN
inx // puts $00
stx CIA1_PRA // connect all the rows
#if CONFIG_KEYBOARD_C128
stx VIC_XSCAN
#endif
#if CONFIG_KEYBOARD_C65
stx C65_EXTKEYS_PR
#endif
dex // puts $FF
cpx CIA1_PRB
beq scnkey_no_keys
#endif // CONFIG_KEY_FAST_SCAN
#endif // CONFIG_JOY2_CURSOR
// Check for control port 1 activity (can interfere with keyboard)
jsr keyboard_disconnect // disconnect all the rows, .X will be $FF
cpx CIA1_PRB // only control port activity will be reported
#if CONFIG_JOY1_CURSOR
bne scnkey_joystick_1 // use joystick for cursor keys
#else
bne scnkey_no_keys // if activity detected do not scan the keyboard
#endif
// Check if KEYTAB is not 0 (happens if more than one bucky key is pressed)
// High byte equal to 0 = table considered invalid
lda KEYTAB+1
beq scnkey_no_keys
// Scan the keyboard matrix
ldy #$FF // offset in key matrix table, $FF for not found yet
#if CONFIG_KEYBOARD_C128
jsr scnkey_128
#endif
#if CONFIG_KEYBOARD_C65
jsr scnkey_65
#endif
ldx #$07
scnkey_matrix_loop:
lda kb_matrix_row_keys, x
sta CIA1_PRA
lda kb_matrix_bucky_filter, x // filter out bucky keys
ora CIA1_PRB
cmp #$FF
beq scnkey_matrix_loop_next // skip if no key pressed from this row
cpy #$FF
bne scnkey_no_keys // jam, more than one key pressed
// We have at least one key pressed in this row, we need to find which one exactly
ldy #$07
scnkey_matrix_loop_inner:
cmp kb_matrix_row_keys, y
bne !+ // not this particular key
tya // now .A contains key offset within a row
clc
adc kb_matrix_row_offsets, x // now .A contains key offset from the matrix start
tay
jmp scnkey_matrix_loop_next
!:
dey
bpl scnkey_matrix_loop_inner
bmi scnkey_no_keys // branch always, multiple keys must have been pressed
scnkey_matrix_loop_next:
dex
bpl scnkey_matrix_loop
// Scanning complete - check if we got a key
cpy #$FF
beq scnkey_no_keys
// To be extra sure, check for possible control port 1 interference once again
jsr keyboard_disconnect // disconnect all the rows, .X will be $FF
cpx CIA1_PRB // only control port activity will be reported
beq scnkey_got_key // branch if joystick activity NOT detected
// FALLTROUGH
scnkey_no_keys:
// Mark no key press
lda #$40
sta LSTX
rts
#if CONFIG_JOY1_CURSOR
scnkey_joystick_1:
// Prepare joystick 1 status
lda CIA1_PRB
and #%00001111 // filter out anything but movement
// FALLTROUGH
#endif
#if CONFIG_JOY1_CURSOR || CONFIG_JOY2_CURSOR
scnkey_joystick_filtered:
// Set appropriate keyboard matrix and key code for joystick event
ldy #$03
!:
cmp kb_matrix_joy_status, y
beq !+
dey
bpl !-
// Not found
rts
!:
// Found
lda kb_matrix_joy_keytab_lo, y
sta KEYTAB+0
lda kb_matrix_joy_keytab_hi, y
sta KEYTAB+1
lda kb_matrix_joy_keytab_idx, y
tay
// FALLTROUGH
#endif
scnkey_got_key: // .Y should now contain the key offset in matrix pointed by KEYTAB
cpy LSTX
beq scnkey_try_repeat // branch if the same key as previously
sty LSTX
// Reset key repeat counters - see [CM64] page 58
// Note: according to [CM64] it should be $10 for initializing DELAY, $06 for
// initializing KOUNT for the first time and $04 for subsequent ones - but replicating
// this would make our implementation longer, probably without improving the compatibility.
//
// Besides - since I am the one who writes the code, I will make the values exactly how I like them :D
lda #$16
sta DELAY
// FALLTROUGH
scnkey_output_key:
// Check if we have free space in the keyboard buffer
lda NDX
cmp XMAX
bcs scnkey_early_repeat // no space in buffer
// Reinitialize secondary counter
lda #$03
sta KOUNT
// Retrieve the PETSCII code
#if CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C65
cpy #$40
bcc !+
#if CONFIG_KEYBOARD_C128
lda kb_matrix_128 - $41, y // retrieve key code from C128 extended matrix
#elif CONFIG_KEYBOARD_C65
// Select key matrix (normal or shifted) for extended C65 keys
lda SHFLAG
and #%00000111 // KEY_FLAG_SHIFT + KEY_FLAG_VENDOR + KEY_FLAG_CTRL
beq scnkey_output_65_no_shift
cmp #KEY_FLAG_SHIFT
// XXX how to behave on VENDOR/CTRL key? Harmonize this with claasic keys behavior
bne scnkey_no_keys // no scanning for this bucky key combination
lda kb_matrix_65_shifted - $41, y
jmp scnkey_got_petscii
scnkey_output_65_no_shift:
lda kb_matrix_65 - $41, y
#endif
jmp scnkey_got_petscii
!:
lda (KEYTAB), y // retrieve key code from standard matrix
#endif // CONFIG_KEYBOARD_C128 or CONFIG_KEYBOARD_C65
#if CONFIG_KEYBOARD_C128_CAPS_LOCK || CONFIG_KEYBOARD_C65_CAPS_LOCK
// Check if we need special handling for a CAPS LOCK key
// This is shorter than a separate set of tables
scnkey_handle_caps_lock:
#if !CONFIG_KEYBOARD_C128 && !CONFIG_KEYBOARD_C65
lda (KEYTAB), y
#endif
tax
lda SHFLAG
and #(%00000111 + KEY_CAPS_LOCK)
cmp #KEY_CAPS_LOCK
bne !+ // branch if no special CAPS LOCK handling needed
cpx #$41 // 'A'
bcc !+
cpx #$5B // 'Z' + 1
bcs !+
txa
clc
adc #$20 // turn lowercase into uppercase
tax
!:
txa
#endif // CONFIG_KEYBOARD_C128_CAPS_LOCK or CONFIG_KEYBOARD_C65_CAPS_LOCK
#if !CONFIG_KEYBOARD_C128 && !CONFIG_KEYBOARD_C128_CAPS_LOCK && !CONFIG_KEYBOARD_C65 && !CONFIG_KEYBOARD_C65_CAPS_LOCK
lda (KEYTAB), y
#endif
// Output PETSCII code to the keyboard buffer
scnkey_got_petscii:
#if CONFIG_KEYBOARD_C128 && CONFIG_EDIT_TABULATORS
// Special handling for SHIFT+TAB; it is easier than creating new matrix
tax
cmp #KEY_TAB_FW
bne !+
lda SHFLAG
and #KEY_FLAG_SHIFT
beq !+
ldx #KEY_TAB_BW
!:
txa
#endif // CONFIG_KEYBOARD_C128 and CONFIG_EDIT_TABULATORS
beq scnkey_no_keys // branch if we have no PETSCII code for this key
ldy NDX
sta KEYD, y
inc NDX
// FALLTROUGH
scnkey_done:
rts
scnkey_try_repeat:
#if !CONFIG_KEY_REPEAT_ALWAYS
// Check whether we should repeat keys - first the flag, afterwards hardcoded list
lda RPTFLG
bmi scnkey_handle_repeat // branch if we should repeat always
tya
ldx #(__kb_matrix_alwaysrepeat_end - kb_matrix_alwaysrepeat - 1)
!:
cmp kb_matrix_alwaysrepeat, x
beq scnkey_handle_repeat
dex
bpl !-
bmi scnkey_done
scnkey_handle_repeat:
#endif // no CONFIG_KEY_REPEAT_ALWAYS
// Countdown before first repeat
lda DELAY
beq !+
dec DELAY
rts
!:
// Countdown before subsequent repeats
lda KOUNT
beq scnkey_output_key // if second counter is also 0, we can repeat the key
dec KOUNT
rts
scnkey_early_repeat:
// Keyboard buffer was full - at least make sure the key
// will be repeated as soon as possible
lda #$00
sta DELAY
sta KOUNT
rts
via_keylog:
jmp (KEYLOG)
#endif // no CONFIG_LEGACY_SCNKEY
+71
View File
@@ -0,0 +1,71 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Keyboard scanning routine extension for C128 keyboards
//
// - [CM128] Computes Mapping the Commodore 128 - pages 212 (SHFLAG), 290 (matrix)
//
#if CONFIG_KEYBOARD_C128 && !CONFIG_LEGACY_SCNKEY
// Inlining this within SCNKEY would both overcomplicate the implementation
// and disrupt a lot of branches (they would cross the 127 bytes distance limit)
// .Y is now $FF - try to put there a key code from extended keyboard
scnkey_128:
sty CIA1_PRA // disconnect all the classic keys first
ldx #$02
scnkey_matrix_128_loop:
lda kb_matrix_row_keys, x
sta VIC_XSCAN
lda kb_matrix_128_bucky_filter, x // filter out bucky keys
ora CIA1_PRB
cmp #$FF
beq scnkey_matrix_128_loop_next // skip if no key pressed from this row
cpy #$FF
bne scnkey_128_no_keys // jam, more than one key pressed
// We have at least one key pressed in this row, we need to find which one exactly
ldy #$07
scnkey_matrix_128_loop_inner:
cmp kb_matrix_row_keys, y
bne !+ // not this particular key
tya // now .A contains key offset within a row
clc
adc kb_matrix_row_offsets, x // now .A contains key offset from the matrix start
adc #$41 // now .A contains offset after the standard matrix
tay
jmp scnkey_matrix_128_loop_next
!:
dey
bpl scnkey_matrix_128_loop_inner
bmi scnkey_128_no_keys // branch always, multiple keys must have been pressed
scnkey_matrix_128_loop_next:
dex
bpl scnkey_matrix_128_loop
// Scanning the C128 keyboard part complete
scnkey_128_done:
stx VIC_XSCAN // $FF, disconnects C128 keys
rts
scnkey_128_no_keys:
pla // get rid of return address from the stack
pla
jmp scnkey_no_keys // pass controll to original routine
#endif // CONFIG_KEYBOARD_C128 and no CONFIG_LEGACY_SCNKEY
+68
View File
@@ -0,0 +1,68 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Keyboard scanning routine extension for C65 keyboards
//
// - [CM128] Computes Mapping the Commodore 128 - pages 212 (SHFLAG)
// - https://github.com/MEGA65/c65-specifications/blob/master/c65manualupdated.txt (matrix)
//
#if CONFIG_KEYBOARD_C65 && !CONFIG_LEGACY_SCNKEY
// Inlining this within SCNKEY would both overcomplicate the implementation
// and disrupt a lot of branches (they would cross the 127 bytes distance limit)
// .Y is now $FF - try to put there a key code from extended keyboard
scnkey_65:
sty CIA1_PRA // disconnect classic keys
lda #$00
sta C65_EXTKEYS_PR // connect C65 keys
lda #%00000101 // filter out bucky keys: ALT, NO_SCRL
ora CIA1_PRB
cmp #$FF
beq scnkey_65_done // skip if no key pressed from this row
// At least one key is pressed - decode it
ldy #$07
scnkey_matrix_65_loop:
cmp kb_matrix_row_keys, y
bne !+ // not this particular key
tya // now .A contains key offset within a row
clc
adc kb_matrix_row_offsets, x // now .A contains key offset from the matrix start
adc #$41 // now .A contains offset after the standard matrix
tay
jmp scnkey_65_done
!:
dey
bpl scnkey_matrix_65_loop
// FALLTROUGH, multiple keys must have been pressed
scnkey_65_no_keys:
pla // get rid of return address from the stack
pla
jmp scnkey_no_keys // pass controll to original routine
scnkey_65_done:
ldx #$FF
stx C65_EXTKEYS_PR // connect C65 keys
rts
#endif // CONFIG_KEYBOARD_C65 and no CONFIG_LEGACY_SCNKEY
+533
View File
@@ -0,0 +1,533 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Official Kernal routine, described in:
//
// - [RG64] C64 Programmers Reference Guide - page 295
// - [CM64] Computes Mapping the Commodore 64 - page 220
//
// CPU registers that has to be preserved (see [RG64]): none
//
// NOTE: The code here is described as legacy, because the algorithm (although working very well)
// requires much more RAM than the original Kernal routine uses; without any form of extended
// RAM available to Open ROMs it will always be a serious compatibility risk.
#if CONFIG_LEGACY_SCNKEY
// Scan the keyboard..
// Here we don't use the horrible buggy original routine,
// not just because of copyright. Instead, we use the
// nice one with joystick interference removal and
// key roll-over support from
// http://codebase64.org/doku.php?id=base:scanning_the_keyboard_the_correct_and_non_kernal_way
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Keyboard IO Routine
// ~~~~~~~~~~~~~~~~~~~
// By: TWW/CTR
// Information
// ~~~~~~~~~~~
// The routine uses "2 Key rollower" or up to 3 if the key-combination doesen't induce shadowing.
// If 2 or 3 keys are pressed simultaneously (within 1 scan) a "No Activity" state has to occur before new valid keys are returned.
// RESTORE is not detectable and must be handled by NMI IRQ.
// SHIFT LOCK is not detected due to unreliability.
// History:
// ~~~~~~~~
// V3.0 - Hacked to pieces by PGS to work as KERNAL keyboard scan routine
// V2.5 - New test tool.
// Added return of error codes.
// Fixed a bug causing Buffer Overflow.
// Fixed a bug in Non Alphanumerical Flags from 2.0.
// V2.1 - Shortened the source by adding .for loops & Updated the header and some comments.
// Added "simultaneous keypress" check.
// V2.0 - Added return of non-Alphanumeric keys into X & Y-Registers.
// Small optimizations here and there.
// V1.1 - Unrolled code to make it faster and optimized other parts of it.
// Removed SHIFT LOCK scanning.
// V1.0 - First Working Version along with test tool.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// Low memory variables
// Reuse RS232 variables, since they should not be used by other things.
// Carefully avoid $A7 which is used by 64NET
.label KeyQuantity = $A8 // 1 byte
.label BufferNew = $A9 // 3 bytes
.label TempZP = $B6 // 1 byte
// These should be initialized in CINT to $FF
.label BufferQuantity = $B4 // 1 byte
.label BufferOld = $293 // 3 bytes
.label Buffer = $297 // 4 bytes
// $250-$258 is the 81st - 88th characters in BASIC input, a carry over from VIC-20
// and not used on C64, so safe for us to use, probably.
.label ScanResult = $250 // 8 bytes
// Operational Variables
.const MaxKeyRollover = 3
SCNKEY:
lda #$00
sta BufferQuantity
// Decrement key repeat timeout if non-zero
ldx KOUNT
beq sk_start
dec KOUNT
sk_start:
// Call main keyboard scanning routine
jsr Main
lda BufferQuantity
beq no_keys_waiting
// Stuff each key pressed into the keyboard buffer
ldy #$00
!:
lda Buffer,y
jsr accept_key
iny
cpy BufferQuantity
bne !-
no_keys_waiting:
rts
accept_key:
// Work out what is new and needs to be added
// to the input buffer.
// Also update the bucky key status flags etc
cmp #$ff
beq sk_nokey
// Got a key, turn it from matrix position to key value,
// and stuff it in the keyboard buffer
// Convert matrix position to key code
// XXX - Add offset of $40, $80 or $C0 if shift, CONTROL or C= are held down
pha
lda SHFLAG
and #$7
tax
pla
and #$3f
ora kb_matrix_lookup,x
tax
lda kb_matrix,x
// But don't insert $00 characters
beq sk_nokey
// Stash key into keyboard buffer
ldx NDX
cpx XMAX
beq sk_nokey
sta KEYD,x
inc NDX
sk_nokey:
rts
// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Routine for Scanning a Matrix Row
KeyInRow:
ldy #7
NextKeyInRow:
ror
bcs nokey
jsr KeyFound
nokey:
inx
dey
bpl NextKeyInRow
rts
// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Routine for handling: Key Found
KeyFound:
stx TempZP
dec KeyQuantity
bmi OverFlow
// Originally, we resolved the keys.
// Now we just return the matrix position, so that
// we can do C64-style bucky modifications as normal
// was: ldy KeyTable,x
pha
txa
ldx KeyQuantity
sta BufferNew,x
pla
ldx TempZP
rts
// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Routine for handling: Overflow
OverFlow:
pla // Dirty hack to handle 2 layers of JSR
pla
pla
pla
// Don't manipulate last legal buffer as the routine will fix itself once it gets valid input again.
ReturnNoKeys:
sec
lda #$00
sta BufferQuantity
lda #$FF
sta LSTX
ldx #MaxKeyRollover-1
!:
sta Buffer,x
sta BufferOld,x
dex
bpl !-
rts
// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Exit Routine for: No Activity
NoActivityDetected:
// So cancel all bucky keys
lda SHFLAG
sta LSTSHF
lda #$00
sta SHFLAG
jmp ReturnNoKeys
// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Configure Data Direction Registers
Main:
// Begin with no key events
lda #$ff
sta BufferNew+0
sta BufferNew+1
sta BufferNew+2
// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Check for Port Activity
ldx #$FF
ldy #$00
sty CIA1_PRA // Connect all Keyboard Rows
cpx CIA1_PRB
bne skip0
jmp NoActivityDetected
JoystickActivity:
// Clear bucky key status
lda #$00
sta SHFLAG
lda CIA1_PRB
and #$03
cmp #$01
bne !+
// down
ldx #$07 // UP/DOWN
jsr KeyFound
!:
cmp #$02
bne !+
// Up
// Mark shift as pressed
ldx #$01
stx SHFLAG
ldx #$07 // UP/DOWN
jsr KeyFound
!:
// Only allow up/down OR left/right, since
// else we have confusing situation with SHIFT required
// for one, but not the other.
// XXX - We could fix this by making the joystick activity
// feed the key input at a higher level, rather than
// simulating directly pressing the cursor keys.
cmp #$03
beq !+
jmp skdone
!:
lda CIA1_PRB
and #$0c
cmp #$04
bne !+
ldx #$02
jsr KeyFound // LEFT/RIGHT
!:
cmp #$08
bne !+
ldx #$01
stx SHFLAG
ldx #$02
jsr KeyFound // LEFT/RIGHT
!:
jmp skdone
skip0:
// // Set max keys allowed before ignoring result
lda #MaxKeyRollover
sta KeyQuantity
// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Check for Control Port #1 Activity
stx CIA1_PRA // Disconnect all Keyboard Rows
cpx CIA1_PRB // Only Control Port activity will be detected
bne JoystickActivity
// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Scan Keyboard Matrix
ldx #7
lda #%11111110
next_row:
sta CIA1_PRA
pha
lda CIA1_PRB
sta ScanResult,x
pla
sec
rol
dex
bpl next_row
// X gets back to $FF here, which is assumed below
// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Check for Control Port #1 Activity (again)
stx CIA1_PRA // Disconnect all Keyboard Rows
cpx CIA1_PRB // Only Control Port activity will be detected
beq !+
jmp ReturnNoKeys
!:
// Make X = $00, assumed below
inx
// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Check and flag Non Alphanumeric Keys
// Store de-bounce data for bucky keys
// (Compute's Mapping the 64, p58-59)
lda SHFLAG
sta LSTSHF
// Build bucky state
lda #$00
sta SHFLAG
lda ScanResult+6
eor #%10000000
and #%10000000 // Left shift
rol
rol
and #$01
ora SHFLAG
sta SHFLAG
// Right shift
lda ScanResult+1
eor #$10
lsr
lsr
lsr
lsr
and #$01
ora SHFLAG
sta SHFLAG
// Control
lda ScanResult+0
eor #$04
and #$04
ora SHFLAG
sta SHFLAG
// Vendor key
lda ScanResult+0
eor #$ff
lsr
lsr
lsr
lsr
and #$02
ora SHFLAG
sta SHFLAG
// Handle SHIFT + VENDOR
jsr scnkey_toggle_if_needed
no_case_toggle:
// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// // Check for pressed key(s)
lda ScanResult+7
cmp #$ff
beq sk6
jsr KeyInRow
sk6:
ldx #8
lda ScanResult+6
beq sk5
jsr KeyInRow
sk5:
ldx #16
lda ScanResult+5
beq sk4
jsr KeyInRow
sk4:
ldx #24
lda ScanResult+4
beq sk3
jsr KeyInRow
sk3:
ldx #32
lda ScanResult+3
beq sk2
jsr KeyInRow
sk2:
ldx #40
lda ScanResult+2
beq sk1
jsr KeyInRow
sk1:
ldx #48
lda ScanResult+1
beq sk0
jsr KeyInRow
sk0:
ldx #56
lda ScanResult+0
beq skdone
jsr KeyInRow
skdone:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Key Scan Completed
// Put any new key (not in old scan) into buffer
ldx #MaxKeyRollover-1
ProcessPressedKeys:
// Check if the currently pressed key is continuing to be held down
lda BufferNew,x
cmp #$ff
beq ConsiderNextKey
cmp BufferOld
beq KeyHeld
cmp BufferOld+1
beq KeyHeld
cmp BufferOld+2
beq KeyHeld
RecordKeypress:
// New Key Detected
ldy BufferQuantity
cpy #MaxKeyRollover
bcc !+
jmp ReturnNoKeys // too many new keys
!:
AcceptKeyEvent:
sta Buffer,y
iny
sty BufferQuantity
ConsiderNextKey:
dex
bpl ProcessPressedKeys
// Copy new presses to old list
ldx #MaxKeyRollover-1
!:
lda BufferNew,x
sta BufferOld,x
dex
bpl !-
// Return success and set of pressed keys
clc
rts
KeyHeld:
// The key in A is still held down.
// compare with key in LSTX
// (Compute's Mapping the 64 p36-37)
// if different, reset repeat count down.
// Ignore bucky keys, so that repeat can work when a
// bucky is held down.
cmp #15
beq BuckyHeld
cmp #52
beq BuckyHeld
cmp #58
beq BuckyHeld
cmp #61
beq BuckyHeld
cmp LSTX
beq SameKeyHeld
// Different key held
sta LSTX
pha
lda DELAY
sta KOUNT
pla
BuckyHeld:
jmp ConsiderNextKey
SameKeyHeld:
pha
lda KOUNT
bmi KeyCanRepeat
bne KeyRepeatWait
// Count down ended, so repeat key now
KeyCanRepeat:
// (Compute's Mapping the 64 p58)
pha
lda #6-2 // Fudge factor to match speed
sta KOUNT
pla
pla
jmp RecordKeypress
KeyRepeatWait:
pla
jmp ConsiderNextKey
#endif // CONFIG_LEGACY_SCNKEY
+85
View File
@@ -0,0 +1,85 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Well-known Kernal routine, described in:
//
// - [CM64] Computes Mapping the Commodore 64 - pages 220, 221
//
scnkey_set_keytab:
#if CONFIG_LEGACY_SCNKEY // routine not compatible with legacy SCNKEY
rts
#else
// Set initial KEYTAB value
lda #<kb_matrix
sta KEYTAB+0
lda #>kb_matrix
sta KEYTAB+1
// Calculate table index
lda SHFLAG
and #$07 // we are only interested in SHIFT / CTRL / VENDOR keys
tax
// Retrieve table offset
lda kb_matrix_lookup, x
cmp #$FF
bne scnkey_valid_offset
// $FF means we shouldn't decode anything, mark this by setting high byte
// of KEYTAB to 0 (I don't think anyone would put keyboard decoding table
// at zeropage)
lda #$00
beq !+ // branch always
scnkey_valid_offset:
// Add offset to the vector
clc
adc KEYTAB+0
sta KEYTAB+0
lda #$00
adc KEYTAB+1
!:
sta KEYTAB+1
// FALLTROUGH
#endif // no CONFIG_LEGACY_SCNKEY
scnkey_toggle_if_needed: // entry for SCNKEY (TWW/CTR version)
// Check if we should toggle the character set
lda MODE
bne !+ // not allowed to toggle
lda SHFLAG
and #$03
cmp #$03
bne !+ // no SHIFT + VENDOR pressed
lda LSTSHF
and #$03
cmp #$03
beq !+ // alreeady toggled
// Toggle char set
lda VIC_YMCSB
eor #$02
sta VIC_YMCSB
!:
rts
+54
View File
@@ -0,0 +1,54 @@
// #LAYOUT# STD * #TAKE
// #LAYOUT# X16 * #IGNORE
// #LAYOUT# * KERNAL_0 #TAKE
// #LAYOUT# * * #IGNORE
//
// Keyboard part of the UDTIM routine, has to preserve .Y
//
udtim_keyboard:
// According to [CM64], page 27, the action we have to perform is to copy
// the last row of keyboard to RAM, so that various routines can detect the STOP
// key press. But something as simple as this would have created warm restart
// with M+N+SPACE+RESTORE due to ghosting - so the original ROM has to provide
// some protection here. I do not know what the mechanism there exactly does,
// but I hope the mechanism below will be compatible enough.
lda #$80
sta CIA1_PRA // select all the rows except the last one
#if CONFIG_KEYBOARD_C128
ldx #$00
stx VIC_XSCAN // connect all the extra C128 keys
#endif
#if CONFIG_KEYBOARD_C65
ldx #$00
stx C65_EXTKEYS_PR // connect all the extra C65 keys
#endif
lda CIA1_PRB // read the keys
eor #$FF
sta STKEY // store reversed state - to filter out anything vulnerable to ghosting
#if CONFIG_KEYBOARD_C128
dex // puts $FF
stx VIC_XSCAN // disconnect the extra C128 keys
#endif
#if CONFIG_KEYBOARD_C65
dex // puts $FF
stx C65_EXTKEYS_PR // disconnect the extra C65 keys
#endif
lda #$7F
sta CIA1_PRA // select the last row (bit to 0)
lda CIA1_PRB // read the row
ora STKEY // filter out what might be the reason of ghosting
sta STKEY
// Leave the CIA configured this way. It would be far better to disconnect
// the keyboard at this point, but certain software (mainly intros) is
// unable to, for example, read the space bar status.
rts