From deac5dcb518b20ebc273b3d2c4b0627b1ae41823 Mon Sep 17 00:00:00 2001 From: FeralChild64 Date: Fri, 11 Oct 2019 22:26:03 +0200 Subject: [PATCH] implemented routine pointed by KEYTAB --- STATUS.md | 2 +- c64/aliases/,aliases_ram_lowmem.s | 2 +- c64/kernal/cint_real.s | 4 +- c64/kernal/scnkey.s | 83 +++++++++++++++++++++++++++++++ c64/kernal/scnkey_set_keytab.s | 53 ++++++++++++++++++++ c64/kernal/setup_keydecode.s | 5 -- 6 files changed, 140 insertions(+), 9 deletions(-) create mode 100644 c64/kernal/scnkey.s create mode 100644 c64/kernal/scnkey_set_keytab.s delete mode 100644 c64/kernal/setup_keydecode.s diff --git a/STATUS.md b/STATUS.md index 73dcd39c..6c5ebc5b 100644 --- a/STATUS.md +++ b/STATUS.md @@ -98,7 +98,7 @@ NOTE: Even the 'DONE' routines won't support features described as missing in on | Address | Unofficial | Name | Status | Remarks | | :-------: | :--------: | :---------- | :------: | :------------------------------------------------: | -| `($028F)` | | `KEYLOG` | NOT DONE | | +| `($028F)` | | `KEYLOG` | DONE | | | `$FF81` | `$FF5B` | `CINT` | DONE | | | `$FF84` | `$FDA3` | `IOINIT` | PARTIAL | CIA initialization incomplete | | `$FF87` | `$FD50` | `RAMTAS` | DONE | | diff --git a/c64/aliases/,aliases_ram_lowmem.s b/c64/aliases/,aliases_ram_lowmem.s index b336613e..e597a011 100644 --- a/c64/aliases/,aliases_ram_lowmem.s +++ b/c64/aliases/,aliases_ram_lowmem.s @@ -153,7 +153,7 @@ .label INSRT = $D8 // insert mode flag/counter .label LDTBL = $D9 // $D9-$F2 screen line link table, [!] our usage is different XXX give more details .label USER = $F3 // $F3-$F4 pointer to current color RAM location - .label KEYTAB = $F5 // $F5-$F6 -- NOT IMPLEMENTED -- + .label KEYTAB = $F5 // $F5-$F6 pointer to keyboard lookup table .label RIBUF = $F7 // $F7-$F8 -- NOT IMPLEMENTED -- .label ROBUF = $F9 // $F9-$FA -- NOT IMPLEMENTED -- // $FB $FB-$FE -- UNUSED -- free for user software diff --git a/c64/kernal/cint_real.s b/c64/kernal/cint_real.s index 21a5490f..dc6088e7 100644 --- a/c64/kernal/cint_real.s +++ b/c64/kernal/cint_real.s @@ -58,9 +58,9 @@ cint_pal: // Setup KEYLOG vector - XXX is it proper place? - lda #setup_keydecode + lda #>scnkey_set_keytab sta KEYLOG+1 cint_brk: // entry for BRK and STOP+RESTORE - XXX, where should it start? diff --git a/c64/kernal/scnkey.s b/c64/kernal/scnkey.s new file mode 100644 index 00000000..a1946dc0 --- /dev/null +++ b/c64/kernal/scnkey.s @@ -0,0 +1,83 @@ + +// +// Official Kernal routine, described in: +// +// - [RG64] C64 Programmer's Reference Guide - page 295 +// - [CM64] Compute's 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 + + +#if !CONFIG_SCNKEY_TWW_CTR + +// Routine is heavily inspired by TWW/CTR proposal, see here: +// - http://codebase64.org/doku.php?id=base:scanning_the_keyboard_the_correct_and_non_kernal_way + + +SCNKEY: + + // Handle repeat timer + + ldx KOUNT + beq sk_start + dec KOUNT + + // Setup the CIA registers + + ldx #$FF + stx CIA1_DDRA // output + ldy #$00 + sty CIA1_DDRB // input + + // Prepare for SHFLAG update + + lda SHFLAG + sta LSTSHF + sty SHFLAG + + // XXX retrieve ALT and NO_SCRL status for C128/C65 keyboards + + // Check for any activity + + sty CIA1_PRA // connect all the lines + cpx CIA1_PRB + beq scnkey_no_keys + + // XXX retrieve SHIFT / CTRL / VENDOR status + + // Set pointer in KEYTAB + jsr scnkey_via_keytab + + // XXX scan the keyboard matrix + + + + + + + + // XXX + +scnkey_no_keys: + + // ldx #$FF + stx LSTX + + rts + +scnkey_via_keytab: + jmp (KEYTAB) + +#endif // No CONFIG_SCNKEY_TWW_CTR diff --git a/c64/kernal/scnkey_set_keytab.s b/c64/kernal/scnkey_set_keytab.s new file mode 100644 index 00000000..e9ae5671 --- /dev/null +++ b/c64/kernal/scnkey_set_keytab.s @@ -0,0 +1,53 @@ + +// +// Well-known Kernal routine, described in: +// +// - [CM64] Compute's Mapping the Commodore 64 - pages 220, 221 +// + +scnkey_set_keytab: + + // Set initial KEYTAB value + + lda #keyboard_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 keyboard_matrix_lookup, x + + // Add offset to the vector + sec + adc KEYTAB+0 + sta KEYTAB+0 + lda #$00 + adc KEYTAB+1 + sta KEYTAB+1 + + // 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 diff --git a/c64/kernal/setup_keydecode.s b/c64/kernal/setup_keydecode.s deleted file mode 100644 index d6010685..00000000 --- a/c64/kernal/setup_keydecode.s +++ /dev/null @@ -1,5 +0,0 @@ - -// XXX provide documentation and implementation - -setup_keydecode: - STUB_IMPLEMENTATION()