C128 keyboard fixes, initial C65 keyboard support

This commit is contained in:
FeralChild64 committed 2019-10-26 13:05:55 +02:00
1 parent 28d0fa5ecf
commit 15c71dcdeb
17 files changed
+252 -53

No files matched your search

+5 -1
View File
@@ -125,7 +125,7 @@ Needs 30-250 more space in KERNAL segment (depending on the features enabled for
### `CONFIG_KEYBOARD_C128`
Allows to use additional keys found on the C128 keyboard. NOTE: might be buggy, on VICE emulator I can't get all the keys working.
Allows to use additional keys found on the C128 keyboard.
Needs about 130 bytes more space in KERNAL segment. If unsure - disable.
@@ -135,6 +135,10 @@ Allows to use CAPS LOCK key on the C128 keyboard, this is independent from `CONF
Needs about 50 bytes more space in KERNAL segment. If unsure - disable.
### `CONFIG_KEYBOARD_C65`, `CONFIG_KEYBOARD_C65_CAPS_LOCK`
Similar, but for C65 keyboard. Please note - the C65 keyboard support is (as of yet) completely untested!
### `CONFIG_KEY_REPEAT_DEFAULT`
Enables key repetition by default during the startup (sets `RPTFLG`).
+1 -1
View File
@@ -3,7 +3,7 @@
Here are the features of the Open ROMs not found in the original ROMs from the 80s (many of them are [configurable](CONFIG.md)):
* improved keyboard scanning, supports anti-ghosting and is resistant to joystick interference (one variant even supports multi-keyy rollover)
* improved keyboard scanning, resistant to ghosting and joystick interference (one variant even supports multi-keyy rollover), supports additional C128 keys
* joystick can be used to move text cursor
* uses RAM under ROM and I/O: 61438 bytes free
* cold/warm start silences multiple SID chips - all $D4xx and $D5xx addresses
+3 -1
View File
@@ -52,8 +52,10 @@
// Keyboard settings
// #define CONFIG_LEGACY_SCNKEY
#define CONFIG_KEYBOARD_C128 // incomplete
#define CONFIG_KEYBOARD_C128
#define CONFIG_KEYBOARD_C128_CAPS_LOCK
// #define CONFIG_KEYBOARD_C65 // untested
// #define CONFIG_KEYBOARD_C65_CAPS_LOCK // untested
// #define CONFIG_KEY_REPEAT_DEFAULT
// #define CONFIG_KEY_REPEAT_ALWAYS
#define CONFIG_KEY_FAST_SCAN
+5 -3
View File
@@ -42,10 +42,10 @@
// Multiple SID support
#define CONFIG_SID_2ND
.const CONFIG_SID_2ND_ADDRESS = $D420
.const CONFIG_SID_2ND_ADDRESS = $D440
// #define CONFIG_SID_3RD
.const CONFIG_SID_3RD_ADDRESS = $D440
.const CONFIG_SID_3RD_ADDRESS = $D420
// #define CONFIG_SID_D4XX
// #define CONFIG_SID_D5XX
@@ -54,8 +54,10 @@
// Keyboard settings
// #define CONFIG_LEGACY_SCNKEY
// #define CONFIG_KEYBOARD_C128 // incomplete
// #define CONFIG_KEYBOARD_C128
// #define CONFIG_KEYBOARD_C128_CAPS_LOCK
#define CONFIG_KEYBOARD_C65 // untested
#define CONFIG_KEYBOARD_C65_CAPS_LOCK // untested
// #define CONFIG_KEY_REPEAT_DEFAULT
// #define CONFIG_KEY_REPEAT_ALWAYS
#define CONFIG_KEY_FAST_SCAN
+3 -1
View File
@@ -53,8 +53,10 @@
// Keyboard settings
#define CONFIG_LEGACY_SCNKEY
// #define CONFIG_KEYBOARD_C128 // incomplete
// #define CONFIG_KEYBOARD_C128
// #define CONFIG_KEYBOARD_C128_CAPS_LOCK
// #define CONFIG_KEYBOARD_C65 // untested
// #define CONFIG_KEYBOARD_C65_CAPS_LOCK // untested
// #define CONFIG_KEY_REPEAT_DEFAULT
// #define CONFIG_KEY_REPEAT_ALWAYS
#define CONFIG_KEY_FAST_SCAN
+3 -1
View File
@@ -52,8 +52,10 @@
// Keyboard settings
// #define CONFIG_LEGACY_SCNKEY
// #define CONFIG_KEYBOARD_C128 // incomplete
// #define CONFIG_KEYBOARD_C128
// #define CONFIG_KEYBOARD_C128_CAPS_LOCK
// #define CONFIG_KEYBOARD_C65 // untested
// #define CONFIG_KEYBOARD_C65_CAPS_LOCK // untested
// #define CONFIG_KEY_REPEAT_DEFAULT
// #define CONFIG_KEY_REPEAT_ALWAYS
#define CONFIG_KEY_FAST_SCAN
+5 -2
View File
@@ -145,13 +145,16 @@
// Check if keyboard options are correct
{
#if CONFIG_LEGACY_SCNKEY && (CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C128_CAPS_LOCK)
.error "CONFIG_LEGACY_SCNKEY and CONFIG_KEYBOARD_C128* are mutually exclusive"
#if CONFIG_LEGACY_SCNKEY && (CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C128_CAPS_LOCK || CONFIG_KEYBOARD_C65 || CONFIG_KEYBOARD_C65_CAPS_LOCK)
.error "CONFIG_LEGACY_SCNKEY and CONFIG_KEYBOARD_C128* / CONFIG_KEYBOARD_C65* are mutually exclusive"
#endif
#if (CONFIG_MB_MEGA_65 || CONFIG_MB_ULTIMATE_64) && (CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C128_CAPS_LOCK)
.error "Selected CONFIG_MB_* is not compatible with CONFIG_KEYBOARD_C128*"
#endif
#if CONFIG_MB_ULTIMATE_64 && (CONFIG_KEYBOARD_C65 || CONFIG_KEYBOARD_C65_CAPS_LOCK)
.error "Selected CONFIG_MB_* is not compatible with CONFIG_KEYBOARD_C65*"
#endif
}
+11
View File
@@ -17,6 +17,17 @@
}
//
// Trick to skip a 2-byte instruction
//
.pseudocommand skip_2_bytes_trash_nvz
{
.byte $2C
}
//
// Stack manipulation - some CPUs will leave .A unchanged, some will use it as temporary storage, so consider .A trashed
//
+23 -12
View File
@@ -16,10 +16,14 @@
.const KEY_FLAG_SHIFT = %00000001
.const KEY_FLAG_VENDOR = %00000010
.const KEY_FLAG_CTRL = %00000100
.const KEY_FLAG_ALT = %00001000 // C65 / C128
.const KEY_CAPS_LOCK = %00010000 // C65 / C128
.const KEY_FLAG_NO_SCRL = %00100000 // C65 / C128, Open ROMs unofficial
#if CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C65
.const KEY_FLAG_ALT = %00001000
#if CONFIG_KEYBOARD_C128_CAPS_LOCK || CONFIG_KEYBOARD_C65_CAPS_LOCK
.const KEY_CAPS_LOCK = %00010000
#endif
.const KEY_FLAG_NO_SCRL = %00100000 // Open ROMs unofficial
#endif
// Note - the following PETSCII codes are currently unassigned, can be used for further extensions:
//
@@ -38,8 +42,10 @@
// PETSCII codes for certain C128 and C65 functionalities XXX implement these
.const KEY_BELL = $07 // C65 / C128, no key
.const KEY_ESC = $1B // C65 / C128
#if CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C65
.const KEY_BELL = $07 // no key, originally CTRL+G
.const KEY_ESC = $1B
#endif
// PETSCII codes for programmable keys
@@ -56,14 +62,18 @@
.const KEY_F7 = $8B
.const KEY_F8 = $8C
.const KEY_F9 = $10 // C65
.const KEY_F10 = $15 // C65
.const KEY_F11 = $16 // C65
.const KEY_F12 = $17 // C65
.const KEY_F13 = $19 // C65
.const KEY_F14 = $1A // C65
#if CONFIG_KEYBOARD_C65
.const KEY_F9 = $10
.const KEY_F10 = $15
.const KEY_F11 = $16
.const KEY_F12 = $17
.const KEY_F13 = $19
.const KEY_F14 = $1A
#endif
.const KEY_HELP = $84 // C65, also used for our C128 support
#if CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C65
.const KEY_HELP = $84 // normally C65 only, also used for our C128 support
#endif
// PETSCII codes for cursor keys
@@ -151,4 +161,5 @@
.const KEY_GT = $3E
.const KEY_QUESTION = $3F
// XXX finish this: $4x, $5x, $6x, $7x, $Ax, $Bx, $Cx, $Dx, $Ex, $Fx
+7
View File
@@ -96,6 +96,13 @@ IOINIT:
// Value checked on original ROM
stx CIA2_DDRA
#if CONFIG_KEYBOARD_C65 || CONFIG_KEYBOARD_C65_CAPS_LOCK
lda #$02
sta C65_EXTKEYS_DDR // output for most keys, input for CAPS LOCK bit
#endif
// Set DDR on CIA2 for IEC bus, VIC-II banking
lda #$3F
sta CIA2_DDRA
+21 -13
View File
@@ -14,7 +14,7 @@ UDTIM:
// after this time we have to reset the clock.
inc TIME+0
bne udtim_update_stkey // done with clock
bne udtim_update_stkey // done with clock
inc TIME+1
bne udtim_clock_rollover
inc TIME+2
@@ -31,25 +31,33 @@ udtim_update_stkey: // entry to be used when interrupts are disabled
// but I hope the mechanism below will be compatible enough.
lda #$80
sta CIA1_PRA // select all the rows except the last one
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
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
lda CIA1_PRB // read the keys
eor #$FF
sta STKEY // store reversed state - to filter out anything vulnerable to ghosting
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
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)
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
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
@@ -63,11 +71,11 @@ udtim_clock_rollover:
// At this point TIME+0 contains 0
lda TIME+1
cmp #$1A
bne udtim_update_stkey // done with clock
bne udtim_update_stkey // done with clock
lda TIME+2
cmp #$4F
bne udtim_update_stkey // done with clock
bne udtim_update_stkey // done with clock
lda #$00
sta TIME+2
sta TIME+1
beq udtim_update_stkey // done with clock - will always jump
beq udtim_update_stkey // done with clock - will always jump
+1 -1
View File
@@ -12,7 +12,7 @@
kb_matrix_128:
.byte KEY_HELP,$38,$38,KEY_TAB_FW,$32,$34,$37,$31
.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
+21
View File
@@ -0,0 +1,21 @@
//
// 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
+22 -4
View File
@@ -5,6 +5,7 @@
// Values based on:
// - [CM64] Compute's Mapping the Commodore 64 - pages 58 (SHFLAG), 173 (matrix)
// - [CM128] Compute's Mapping the Commodore 128 - pages 212 (SHFLAG), 290 (matrix)
// - https://github.com/MEGA65/c65-specifications/blob/master/c65manualupdated.txt
//
#if !CONFIG_LEGACY_SCNKEY
@@ -16,12 +17,11 @@ kb_matrix_bucky_confmask: // values to be written to CIA1_PRA
.byte %10111111 // SHIFT (right)
.byte %01111111 // VENDOR
.byte %01111111 // CTRL
#if CONFIG_KEYBOARD_C128
.byte %11111111 // C128 extra keys
#if CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C65
.byte %11111111 // C128 / C65 extra keys
.byte %11111111
#endif
__kb_matrix_bucky_confmask_end:
@@ -39,6 +39,20 @@ kb_matrix_bucky_confmask_c128: // values to be written to VIC_XSCAN
#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
@@ -50,6 +64,10 @@ kb_matrix_bucky_testmask: // for AND with CIA1_PRB value
.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
@@ -58,7 +76,7 @@ kb_matrix_bucky_shflag: // mask to be ORed to SHFLAG to mark key status
.byte KEY_FLAG_SHIFT
.byte KEY_FLAG_VENDOR
.byte KEY_FLAG_CTRL
#if CONFIG_KEYBOARD_C128
#if CONFIG_KEYBOARD_C128 || CONFIG_KEYBOARD_C65
.byte KEY_FLAG_ALT
.byte KEY_FLAG_NO_SCRL
#endif
+54 -7
View File
@@ -76,6 +76,23 @@ SCNKEY:
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)
@@ -85,6 +102,10 @@ scnkey_bucky_loop:
#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
@@ -123,6 +144,9 @@ scnkey_bucky_loop:
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
@@ -153,6 +177,9 @@ scnkey_bucky_loop:
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:
@@ -280,17 +307,37 @@ scnkey_output_key:
// Retrieve the PETSCII code
#if CONFIG_KEYBOARD_C128
#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
// XXX this will be needed for extended screen editor
// XXX this will be needed for extended screen editor and C128 keyboard
// cmp KEY_TAB_FW // special handling for SHIFT+TAB
// bne scnkey_got_petscii // XXX or to scnkey_handle_caps_lock
@@ -302,16 +349,16 @@ scnkey_output_key:
// !:
// lda KEY_TAB_BW // bne scnkey_got_petscii if CAPS LOCK is handled
#endif // CONFIG_KEYBOARD_C128_CAPS_LOCK
#endif // CONFIG_KEYBOARD_C128 or CONFIG_KEYBOARD_C65
#if CONFIG_KEYBOARD_C128_CAPS_LOCK
#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
#if !CONFIG_KEYBOARD_C128 && !CONFIG_KEYBOARD_C65
lda (KEYTAB), y
#endif
tax
@@ -332,9 +379,9 @@ scnkey_handle_caps_lock:
!:
txa
#endif // CONFIG_KEYBOARD_C128_CAPS_LOCK
#endif // CONFIG_KEYBOARD_C128_CAPS_LOCK or CONFIG_KEYBOARD_C65_CAPS_LOCK
#if !CONFIG_KEYBOARD_C128 && !CONFIG_KEYBOARD_C128_CAPS_LOCK
#if !CONFIG_KEYBOARD_C128 && !CONFIG_KEYBOARD_C128_CAPS_LOCK && !CONFIG_KEYBOARD_C65 && !CONFIG_KEYBOARD_C65_CAPS_LOCK
lda (KEYTAB), y
+2 -6
View File
@@ -48,15 +48,11 @@ scnkey_matrix_128_loop_next:
dex
bpl scnkey_matrix_128_loop
// Scanning the C128 keyboard part complete - check if we got a key
cpy #$FF
beq scnkey_128_done
// Continue with C64 keyboard scanning
// Scanning the C128 keyboard part complete
scnkey_128_done:
stx VIC_XSCAN // $FF, disconnects C128 keys
rts
+65
View File
@@ -0,0 +1,65 @@
//
// Keyboard scanning routine extension for C65 keyboards
//
// - [CM128] Compute's 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