From 677e5452a6cf04e8eeeaf7b87f32a2830b4fe6f2 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Mon, 14 Oct 2019 18:37:46 +0200 Subject: [PATCH] further work on new SCNKEY --- STATUS.md | 94 +++++++++--------- c64/,,config_generic.s | 4 +- c64/,,config_mega65.s | 4 +- c64/,,config_ultimate64.s | 4 +- c64/kernal/interrupts/udtim.s | 11 +-- c64/kernal/keyboard/kb_matrix_lookup.s | 32 +++--- .../keyboard/kb_matrix_lookup_tww_ctr.s | 28 ++++++ c64/kernal/keyboard/keyboard_disconnect.s | 12 +++ c64/kernal/keyboard/scnkey.s | 98 ++++++++++++++++--- c64/kernal/keyboard/scnkey_set_keytab.s | 26 +++++ c64/kernal/keyboard/scnkey_tww_ctr.s | 2 +- 11 files changed, 228 insertions(+), 87 deletions(-) create mode 100644 c64/kernal/keyboard/kb_matrix_lookup_tww_ctr.s create mode 100644 c64/kernal/keyboard/keyboard_disconnect.s diff --git a/STATUS.md b/STATUS.md index 4195a6ba..7b320fe7 100644 --- a/STATUS.md +++ b/STATUS.md @@ -96,53 +96,53 @@ NOTE: Even the 'DONE' routines won't support features described as missing in on
-| Address | Unofficial | Name | Status | Remarks | -| :-------: | :--------: | :---------- | :------: | :------------------------------------------------: | -| `($028F)` | | `KEYLOG` | DONE | | -| `$FF81` | `$FF5B` | `CINT` | DONE | | -| `$FF84` | `$FDA3` | `IOINIT` | PARTIAL | CIA initialization incomplete | -| `$FF87` | `$FD50` | `RAMTAS` | DONE | | -| `$FF8A` | `$FD15` | `RESTOR` | DONE | | -| `$FF8D` | `$FD1A` | `VECTOR` | DONE | | -| `$FF90` | | `SETMSG` | DONE | | -| `$FF93` | | `SECOND` | DONE | | -| `$FF96` | | `TKSA` | DONE | | -| `$FF99` | | `MEMTOP` | DONE | | -| `$FF9C` | | `MEMBOT` | DONE | | -| `$FF9F` | | `SCNKEY` | PARTIAL | future complete version has compatibility problems | -| `$FFA2` | | `SETTMO` | DONE | | -| `$FFA5` | | `ACPTR` | DONE | | -| `$FFA8` | | `CIOUT` | DONE | | -| `$FFAB` | | `UNTLK` | DONE | | -| `$FFAE` | | `UNLSN` | DONE | | -| `$FFB1` | | `LISTEN` | DONE | | -| `$FFB4` | | `TALK` | DONE | | -| `$FFB7` | | `READST` | DONE | | -| `$FFBA` | | `SETFLS` | DONE | | -| `$FFBD` | | `SETNAM` | DONE | | -| `$FFC0` | `$F34A` | `OPEN` | DONE | | -| `$FFC3` | `$F291` | `CLOSE` | DONE | | -| `$FFC6` | `$F20E` | `CHKIN` | DONE | | -| `$FFC9` | `$F250` | `CKOUT` | PARTIAL | | -| `$FFCC` | `$F333` | `CLRCHN` | DONE | | -| `$FFCF` | `$F157` | `CHRIN` | PARTIAL | | -| `$FFD2` | `$F1CA` | `CHROUT` | PARTIAL | | -| `$FFD5` | `$F49E` | `LOAD` | PARTIAL | not yet clear what's this entry doing | -| `($0330)` | `$F4A5` | `LOAD` | PARTIAL | no VERIFY support, no STOP key, check $F49E addr | -| `$FFD8` | `$F5DD` | `SAVE` | NOT DONE | | -| `($0332)` | `$F5ED` | `SAVE` | NOT DONE | | -| `$FFDB` | | `SETTIM` | DONE | | -| `$FFDE` | | `RDTIM` | DONE | | -| `$FFE1` | `$F6ED` | `STOP` | DONE | | -| `$FFE4` | `$F13E` | `GETIN` | PARTIAL | only some devices supported | -| `$FFE7` | `$F32F` | `CLALL` | DONE | | -| `$FFEA` | | `UDTIM` | DONE | | -| `$FFED` | | `SCREEN` | DONE | | -| `$FFF0` | `$E50A` | `PLOT` | DONE | | -| `$FFF3` | | `IOBASE` | DONE | | -| `($FFFA)` | | NMI vec | PARTIAL | | -| `($FFFC)` | | RESET vec | PARTIAL | | -| `($FFFE)` | | IRQ/BRK vec | PARTIAL | | +| Address | Unofficial | Name | Status | Remarks | +| :-------: | :--------: | :---------- | :------: | :--------------------------------------------------: | +| `($028F)` | | `KEYLOG` | DONE | works differently on purpose, to improve kb scanning | +| `$FF81` | `$FF5B` | `CINT` | DONE | | +| `$FF84` | `$FDA3` | `IOINIT` | PARTIAL | CIA initialization incomplete | +| `$FF87` | `$FD50` | `RAMTAS` | DONE | | +| `$FF8A` | `$FD15` | `RESTOR` | DONE | | +| `$FF8D` | `$FD1A` | `VECTOR` | DONE | | +| `$FF90` | | `SETMSG` | DONE | | +| `$FF93` | | `SECOND` | DONE | | +| `$FF96` | | `TKSA` | DONE | | +| `$FF99` | | `MEMTOP` | DONE | | +| `$FF9C` | | `MEMBOT` | DONE | | +| `$FF9F` | | `SCNKEY` | PARTIAL | future complete version has compatibility problems | +| `$FFA2` | | `SETTMO` | DONE | | +| `$FFA5` | | `ACPTR` | DONE | | +| `$FFA8` | | `CIOUT` | DONE | | +| `$FFAB` | | `UNTLK` | DONE | | +| `$FFAE` | | `UNLSN` | DONE | | +| `$FFB1` | | `LISTEN` | DONE | | +| `$FFB4` | | `TALK` | DONE | | +| `$FFB7` | | `READST` | DONE | | +| `$FFBA` | | `SETFLS` | DONE | | +| `$FFBD` | | `SETNAM` | DONE | | +| `$FFC0` | `$F34A` | `OPEN` | DONE | | +| `$FFC3` | `$F291` | `CLOSE` | DONE | | +| `$FFC6` | `$F20E` | `CHKIN` | DONE | | +| `$FFC9` | `$F250` | `CKOUT` | PARTIAL | | +| `$FFCC` | `$F333` | `CLRCHN` | DONE | | +| `$FFCF` | `$F157` | `CHRIN` | PARTIAL | | +| `$FFD2` | `$F1CA` | `CHROUT` | PARTIAL | | +| `$FFD5` | `$F49E` | `LOAD` | PARTIAL | not yet clear what's this entry doing | +| `($0330)` | `$F4A5` | `LOAD` | PARTIAL | no VERIFY support, no STOP key, check $F49E addr | +| `$FFD8` | `$F5DD` | `SAVE` | NOT DONE | | +| `($0332)` | `$F5ED` | `SAVE` | NOT DONE | | +| `$FFDB` | | `SETTIM` | DONE | | +| `$FFDE` | | `RDTIM` | DONE | | +| `$FFE1` | `$F6ED` | `STOP` | DONE | | +| `$FFE4` | `$F13E` | `GETIN` | PARTIAL | only some devices supported | +| `$FFE7` | `$F32F` | `CLALL` | DONE | | +| `$FFEA` | | `UDTIM` | DONE | | +| `$FFED` | | `SCREEN` | DONE | | +| `$FFF0` | `$E50A` | `PLOT` | DONE | | +| `$FFF3` | | `IOBASE` | DONE | | +| `($FFFA)` | | NMI vec | PARTIAL | | +| `($FFFC)` | | RESET vec | PARTIAL | | +| `($FFFE)` | | IRQ/BRK vec | PARTIAL | |
diff --git a/c64/,,config_generic.s b/c64/,,config_generic.s index de70aaac..60c34491 100644 --- a/c64/,,config_generic.s +++ b/c64/,,config_generic.s @@ -58,7 +58,9 @@ #define CONFIG_PANIC_SCREEN #define CONFIG_DOS_WEDGE #define CONFIG_BCD_SAFE_INTERRUPTS -#define CONFIG_SCNKEY_TWW_CTR // for now has to be enabled +// #define CONFIG_SCNKEY_TWW_CTR // XXX document this +#define CONFIG_JOY1_CURSOR // XXX document this +#define CONFIG_JOY2_CURSOR // XXX document this // Debug options diff --git a/c64/,,config_mega65.s b/c64/,,config_mega65.s index 8cd04b0e..8f94243e 100644 --- a/c64/,,config_mega65.s +++ b/c64/,,config_mega65.s @@ -60,7 +60,9 @@ #define CONFIG_PANIC_SCREEN #define CONFIG_DOS_WEDGE #define CONFIG_BCD_SAFE_INTERRUPTS -#define CONFIG_SCNKEY_TWW_CTR // for now has to be enabled +#define CONFIG_SCNKEY_TWW_CTR // XXX document this +#define CONFIG_JOY1_CURSOR // XXX document this +#define CONFIG_JOY2_CURSOR // XXX document this // Debug options diff --git a/c64/,,config_ultimate64.s b/c64/,,config_ultimate64.s index 7578d183..6a1a0e5b 100644 --- a/c64/,,config_ultimate64.s +++ b/c64/,,config_ultimate64.s @@ -58,7 +58,9 @@ #define CONFIG_PANIC_SCREEN #define CONFIG_DOS_WEDGE #define CONFIG_BCD_SAFE_INTERRUPTS -#define CONFIG_SCNKEY_TWW_CTR // for now has to be enabled +// #define CONFIG_SCNKEY_TWW_CTR // XXX document this +#define CONFIG_JOY1_CURSOR // XXX document this +#define CONFIG_JOY2_CURSOR // XXX document this // Debug options diff --git a/c64/kernal/interrupts/udtim.s b/c64/kernal/interrupts/udtim.s index 2d8aac00..34528613 100644 --- a/c64/kernal/interrupts/udtim.s +++ b/c64/kernal/interrupts/udtim.s @@ -25,18 +25,17 @@ udtim_update_stkey: // entry to be used when interrupts are disabled // Another 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 - // XXX scnkey contains similar sequence - deduplicate this! - lda #$FF - sta CIA1_DDRA // output - lda #$00 - sta CIA1_DDRB // input lda #$7F sta CIA1_PRA // select the last row (bit to 0) lda CIA1_PRB // read the row sta STKEY - rts + + // Finish by disconnecting the keyboard, this will prevent + // interference when scanning joystick in port 1 + + jmp keyboard_disconnect udtim_clock_rollover: diff --git a/c64/kernal/keyboard/kb_matrix_lookup.s b/c64/kernal/keyboard/kb_matrix_lookup.s index 53f55497..93477737 100644 --- a/c64/kernal/keyboard/kb_matrix_lookup.s +++ b/c64/kernal/keyboard/kb_matrix_lookup.s @@ -1,21 +1,23 @@ // -// 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 +// 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_SCNKEY_TWW_CTR kb_matrix_lookup: - .byte (__kb_matrix_normal - kb_matrix) // Normal - .byte (__kb_matrix_shift - kb_matrix) // SHIFT - .byte (__kb_matrix_ctrl - kb_matrix) // CTRL - .byte (__kb_matrix_ctrl - kb_matrix) // CTRL + SHIFT - .byte (__kb_matrix_vendor - kb_matrix) // VENDOR - .byte (__kb_matrix_vendor - kb_matrix) // VENDOR + SHIFT - .byte (__kb_matrix_ctrl - kb_matrix) // VENDOR + CTRL - .byte (__kb_matrix_ctrl - kb_matrix) // VENDOR + CTRL + SHIFT + .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 diff --git a/c64/kernal/keyboard/kb_matrix_lookup_tww_ctr.s b/c64/kernal/keyboard/kb_matrix_lookup_tww_ctr.s new file mode 100644 index 00000000..cc7d6e09 --- /dev/null +++ b/c64/kernal/keyboard/kb_matrix_lookup_tww_ctr.s @@ -0,0 +1,28 @@ + +// +// 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_SCNKEY_TWW_CTR + +kb_matrix_lookup_tww_ctr: + + .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_SCNKEY_TWW_CTR diff --git a/c64/kernal/keyboard/keyboard_disconnect.s b/c64/kernal/keyboard/keyboard_disconnect.s new file mode 100644 index 00000000..12708fb6 --- /dev/null +++ b/c64/kernal/keyboard/keyboard_disconnect.s @@ -0,0 +1,12 @@ + +// +// Helper routine - disconnects the keyboard from CIA1_PRB, +// leaves $FF in .X (behavior needed in some places) + + +keyboard_disconnect: + + ldx #$FF + stx CIA1_PRA // disconnect all the rows + + rts diff --git a/c64/kernal/keyboard/scnkey.s b/c64/kernal/keyboard/scnkey.s index 4c8689a5..d79f183f 100644 --- a/c64/kernal/keyboard/scnkey.s +++ b/c64/kernal/keyboard/scnkey.s @@ -23,8 +23,9 @@ // XXX add Commodore 128 keyboard support // XXX add Commodore 65 keybopard support -// XXX add support for using joystick to move sursor keys -// XXX explicitly prevent joystick port 1 interference +// XXX add support for using joysticks to move cursor keys +// XXX add support for keys which are repeated always + #if !CONFIG_SCNKEY_TWW_CTR @@ -46,7 +47,7 @@ SCNKEY: // Check for any activity lda #$00 - sta CIA1_PRA // connect all the rows + sta CIA1_PRA // connect all the rows ldx #$FF cpx CIA1_PRB beq scnkey_no_keys @@ -71,18 +72,44 @@ scnkey_bucky_loop: jsr via_keylog // XXX for some CPUs we have indirect jsr - // Check if we have free space in the keyboard buffer + // 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 - lda NDX - cmp XMAX - bcs scnkey_no_keys // no space in keyboard buffer - do not waste time +#if CONFIG_JOY2_CURSOR - // XXX check for joystick activity + // XXX why this does not work??? + + // 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 + // stx CIA1_DDRA // set port back to output + + // and #%00001111 // filter out anything but joystick movement + // bne scnkey_joystick_a_filtered + +#endif + + // 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_x // use joystick for cursor keys +#else + bne scnkey_no_keys // if activity detected do not scan the keyboard +#endif // Scan the keyboard matrix + ldy #$FF // offset in key matrix table, $FF for not found yet ldx #$07 // XXX adapt for C128 and C65 keyboards - ldy #$FF // offset in key matrix table, $FF for not found yet scnkey_matrix_loop: lda kb_matrix_row_keys, x sta CIA1_PRA @@ -110,9 +137,16 @@ scnkey_matrix_loop_next: dex bpl scnkey_matrix_loop - // Scanning complete + // Scanning complete - check if we got a key + cpy #$FF - bne scnkey_got_key + 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 @@ -125,6 +159,25 @@ scnkey_no_keys: rts +#if CONFIG_JOY1_CURSOR || CONFIG_JOY2_CURSOR + +scnkey_joystick_x: + + // Handle joystick activity (in .X) as cursor keys + + txa + and #%00001111 // filter out anything but movement + + // FALLTROUGH + +scnkey_joystick_a_filtered: + + // XXX finish the implementation + + rts + +#endif + scnkey_got_key: // .Y should now contain the key offset in matrix pointed by KEYTAB cpy LSTX @@ -148,6 +201,12 @@ scnkey_got_key: // .Y should now contain the key offset in matrix pointed by KEY 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 XXX set timer to trigger repeat the next time + // Reinitialize secondary counter lda #$03 @@ -170,12 +229,10 @@ scnkey_handle_repeat: // Check whether we should repeat keys - // XXX some keys should be repeat always! - lda RPTFLG bpl scnkey_done // branch if we should do no repeat - // First countdown (for the first repeat) + // Countdown before first repeat lda DELAY beq !+ @@ -183,7 +240,7 @@ scnkey_handle_repeat: rts !: - // Second countdown (for both first and subsequential repeats) + // Countdown before subsequent repeats lda KOUNT beq scnkey_output_key // if second counter is also 0, we can repeat the key @@ -191,6 +248,17 @@ scnkey_handle_repeat: 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) diff --git a/c64/kernal/keyboard/scnkey_set_keytab.s b/c64/kernal/keyboard/scnkey_set_keytab.s index 27fcfef1..4f9781aa 100644 --- a/c64/kernal/keyboard/scnkey_set_keytab.s +++ b/c64/kernal/keyboard/scnkey_set_keytab.s @@ -5,8 +5,17 @@ // - [CM64] Compute's Mapping the Commodore 64 - pages 220, 221 // + scnkey_set_keytab: + +#if CONFIG_SCNKEY_TWW_CTR // routine not compatible with legacy SCNKEY + + rts + +#else + + // Set initial KEYTAB value lda #