User Tools

Site Tools


base:reading_the_keyboard
no way to compare when less than two revisions

Differences

This shows you the differences between two versions of the page.


base:reading_the_keyboard [2015-04-17 04:33] (current) – created - external edit 127.0.0.1
Line 1: Line 1:
 +====== Reading the Keyboard ======
 +
 +Information from various sources. Collected and partly written by FTC.
 +
 +Reading the keyboard on the Commodore 64 (and C=128) can be done in two main ways. The first way is to use KERNAL routines. The benefit of this is that these routines will do a lot of work for you, and it will handle things like English keyboard layout versus Swedish keyboard layout. Different keyboard layout differs both with respect to what characters that are assigned to what keys, and with respect to the actual characters that are available on the keyboard. For example, Swedish C64 keyboards have the characters Å, Ä and Ö. On the other hand, using KERNAL might not be the way to go in case the default handling of the keyboard does not suit the purposes of your program.
 +
 +The second way to read the keyboard is by accessing hardware registers related to the keyboard directly. This is mainly done by reading $DC01 and $DC02 (i.e. CIA1). The benefit of using this approach is especially salient when you have special needs not covered by the KERNAL routines, or when you are rather interested in the physical location of the keys than what character that is printed on them on the keyboard. An example: The JCH music editor is a bit weird to use when you use a Swedish C64 with Swedish keyboard layout because the functions of the editor are not actually associated with the physical locations of the keys on the keyboards, but with certain characters like ":". This means that the actual key to press is located at different places depending on what machine you use, and in this case, the key you need to press on a Swedish keyboard is less conveniently placed (in some cases the differences may even require the user to press SHIFT, or similar, to get the right character). Imagine that you wrote a game where you control the movement of the character with the keyboard and you use keys that you expect to be next to each other on the keyboard. You would not like this to be changed in some weird way in case someone happens not to use an English C64...
 +
 +Below are some code examples, as well as links to code available in other articles here on Codebase. Also check out some of the books in the [[books:start|books]] section for more info on reading the keyboard.
 +
 +===== Reading keyboard through KERNAL routines =====
 +
 +Here are links to some material on Codebase that shows examples of how to use the KERNAL routines for reading keyboard input:
 +
 +  * [[base:robust_string_input|Robust String Input]] - by Schema
 +  * [[base:ip_address_input|IP Address Input]] - by Schema
 +
 +
 +===== Reading keyboard directly through hardware =====
 +
 +==== Simple case: One key at a time ====
 +
 +Here is a simple example of using the hardware directly to read the keyboard. Written by Groepaz in ca65 assembler format. Simple keychecking (one key at a time, no extras):
 +
 +<code>
 +minikey:
 + lda #$0
 + sta $dc03 ; port b ddr (input)
 + lda #$ff
 + sta $dc02 ; port a ddr (output)
 +
 + lda #$00
 + sta $dc00 ; port a
 + lda $dc01       ; port b
 + cmp #$ff
 + beq nokey
 + ; got column
 + tay
 +
 + lda #$7f
 + sta nokey2+1
 + ldx #8
 +nokey2:
 + lda #0
 + sta $dc00 ; port a
 +
 + sec
 + ror nokey2+1
 + dex
 + bmi nokey
 +
 + lda $dc01       ; port b
 + cmp #$ff
 + beq nokey2
 +
 + ; got row in X
 + txa
 + ora columntab,y
 +
 + sec
 + rts
 +
 +nokey:
 + clc
 + rts
 +
 +columntab:
 + .repeat 256,count
 + .if count = ($ff-$80)
 + .byte $70
 + .elseif count = ($ff-$40)
 + .byte $60
 + .elseif count = ($ff-$20)
 + .byte $50
 + .elseif count = ($ff-$10)
 + .byte $40
 + .elseif count = ($ff-$08)
 + .byte $30
 + .elseif count = ($ff-$04)
 + .byte $20
 + .elseif count = ($ff-$02)
 + .byte $10
 + .elseif count = ($ff-$01)
 + .byte $00
 + .else
 + .byte $ff
 + .endif
 + .endrepeat
 +</code>
 +
 +==== Shift key + one other key ====
 +
 +This code was written by Oswald.
 +
 +<code>
 +lastkey = $10
 +actkey = $11
 +mask = $12
 +
 +matrixlo = $13
 +matrixhi = $14
 +
 +table = $0f00
 +
 + *= $1000
 +
 + lda #$37
 + sta $01
 + jsr $e544
 +
 + sei
 + lda #$35
 + sta $01
 +
 + ldx #$00
 + lda #$00
 +- sta table,x
 + dex
 + bne -
 +
 + lda #$ff
 + sta lastkey
 +
 + lda #$08 ;helper table to index into keyboard matrix
 + sta table+%01111111
 + lda #$07
 + sta table+%10111111
 + lda #$06
 + sta table+%11011111
 + lda #$05
 + sta table+%11101111
 + lda #$04
 + sta table+%11110111
 + lda #$03
 + sta table+%11111011
 + lda #$02
 + sta table+%11111101
 + lda #$01
 + sta table+%11111110
 +
 + lda #$08 ;left shift and another key
 + sta table+%01111111
 + lda #$07
 + sta table+%00111111
 + lda #$06
 + sta table+%01011111
 + lda #$05
 + sta table+%01101111
 + lda #$04
 + sta table+%01110111
 + lda #$03
 + sta table+%01111011
 + lda #$02
 + sta table+%01111101
 + lda #$01
 + sta table+%01111110
 +
 + lda #$08 ;right shift and another key
 + sta table+%01101111
 + lda #$07
 + sta table+%10101111
 + lda #$06
 + sta table+%11001111
 + lda #$05
 + sta table+%11101111
 + lda #$04
 + sta table+%11100111
 + lda #$03
 + sta table+%11101011
 + lda #$02
 + sta table+%11101101
 + lda #$01
 + sta table+%11101110
 +
 +
 + ;endless dummy 
 +
 +uu jsr keyscan
 + lda actkey
 + cmp #$ff ;$ff= no key pressed
 + beq +
 + cmp #$40 ;convert to screen codes
 + bmi ok
 + sec
 + sbc #$40
 +ok
 + sta $0400
 ++ jmp uu
 +
 +
 +
 +
 +
 +keyscan
 + lda #%11111110
 + sta mask
 +
 + lda #%11111101
 + sta $dc00
 + lda $dc01
 + and #%10000000
 + beq shifted ;left shift pressed
 +
 + lda #%10111111
 + sta $dc00
 + lda $dc01
 + and #%00010000
 + beq shifted ;right shift pressed
 +
 + lda #<keytabunshifted
 + sta matrixlo
 + lda #>keytabunshifted
 + sta matrixhi
 + jmp scan
 +
 +shifted
 + lda #<keytabshifted
 + sta matrixlo
 + lda #>keytabshifted
 + sta matrixhi
 +
 +scan ldx #$07
 +
 +rowloop
 + lda mask
 + sta $dc00
 + ldy $dc01
 + lda table,y
 + beq next
 +
 + tay
 + lda (matrixlo),y
 + cmp #$01
 + beq next ;skip left shift
 + cmp #$02
 + beq next ;skip right shift
 + cmp lastkey
 + beq debounce
 + sta lastkey
 + sta actkey
 + rts
 +
 +next
 + sec
 + rol mask
 +
 + lda matrixlo
 + clc
 + adc #$09
 + sta matrixlo
 + bcc *+4
 + inc matrixhi
 +
 + dex
 + bpl rowloop
 + rts
 +
 +debounce lda #$ff
 + sta actkey
 + rts
 +
 + ;unshifted
 +
 +keytabunshifted
 +
 + .byte $ff,$14,$0D,$1D,$88,$85,$86,$87,$11 ;0
 + .byte $ff,$33,$57,$41,$34,$5A,$53,$45,$01 ;1
 + .byte $ff,$35,$52,$44,$36,$43,$46,$54,$58 ;2
 + .byte $ff,$37,$59,$47,$38,$42,$48,$55,$56 ;3
 + .byte $ff,$39,$49,$4A,$30,$4D,$4B,$4F,$4E ;4
 + .byte $ff,$2B,$50,$4C,$2D,$2E,$3A,$40,$2C ;5
 + .byte $ff,$5C,$2A,$3B,$13,$01,$3D,$5E,$2F ;6
 + .byte $ff,$31,$5F,$04,$32,$20,$02,$51,$03 ;7
 + .byte $ff
 +
 +keytabshifted
 + .byte $ff,$94,$8D,$9D,$8C,$89,$8A,$8B,$91
 + .byte $ff,$23,$D7,$C1,$24,$DA,$D3,$C5,$01
 + .byte $ff,$25,$D2,$C4,$26,$C3,$C6,$D4,$D8
 + .byte $ff,$27,$D9,$C7,$28,$C2,$C8,$D5,$D6
 + .byte $ff,$29,$C9,$CA,$30,$CD,$CB,$CF,$CE
 + .byte $ff,$DB,$D0,$CC,$DD,$3E,$5B,$BA,$3C
 + .byte $ff,$A9,$C0,$5D,$93,$01,$3D,$DE,$3F
 + .byte $ff,$21,$5F,$04,$22,$A0,$02,$D1,$83
 + .byte $ff
 +
 +
 + ;one extra $ff column is added, because the zero value is used to detect unpressed kays
 +</code>
 +
 +==== Handling three keys pressed at once ====
 +
 +For a more complex routine, see "[[magazines:chacking6#three-key_rollover_for_the_c-128_and_c-64|THREE-KEY ROLLOVER for the C=128 and C=64]]” written by Craig Bruce and published in C=Hacking #6. It allows up to three keys pressed at once and also includes info on differences between C128 and C64 with respect to keyboard reading.
 +
 +==== $DC00/$DC01 reference for English keyboards ====
 +
 +Here is a reference table typed in by TWW that shows the characters assigned to the various keys on an English keyboard (but keep in mind that this table would actually look slightly different for a Swedish or German keyboard for example).
 +
 +<code>
 ++----+----------------------+-------------------------------------------------------------------------------------------------------+
 +|    |                      |                                Peek from $dc01 (code in paranthesis):                                 |
 +|row:| $dc00:               +------------+------------+------------+------------+------------+------------+------------+------------+
 +|    |                      |   BIT 7    |   BIT 6    |   BIT 5    |   BIT 4    |   BIT 3    |   BIT 2    |   BIT 1    |   BIT 0    |
 ++----+----------------------+------------+------------+------------+------------+------------+------------+------------+------------+
 +|1.  | #%11111110 (254/$fe) | DOWN  ($  )|   F5  ($  )|   F3  ($  )|   F1  ($  )|   F7  ($  )| RIGHT ($  )| RETURN($  )|DELETE ($  )|
 +|2.  | #%11111101 (253/$fd) |LEFT-SH($  )|     ($05)|     ($13)|     ($1a)|     ($34)|     ($01)|     ($17)|     ($33)|
 +|3.  | #%11111011 (251/$fb) |     ($18)|     ($14)|     ($06)|     ($03)|     ($36)|     ($04)|     ($12)|     ($35)|
 +|4.  | #%11110111 (247/$f7) |     ($16)|     ($15)|     ($08)|     ($02)|     ($38)|     ($07)|     ($19)|     ($37)|
 +|5.  | #%11101111 (239/$ef) |     ($0e)|     ($0f)|     ($0b)|     ($0d)|     ($30)|     ($0a)|     ($09)|     ($39)|
 +|6.  | #%11011111 (223/$df) |   ,   ($2c)|     ($00)|   :   ($3a)|     ($2e)|     ($2d)|     ($0c)|     ($10)|     ($2b)|
 +|7.  | #%10111111 (191/$bf) |   /   ($2f)|     ($1e)|     ($3d)|RGHT-SH($  )|  HOME ($  )|   ;   ($3b)|     ($2a)|   £   ($1c)|
 +|8.  | #%01111111 (127/$7f) | STOP  ($  )|     ($11)|COMMODR($  )| SPACE ($20)|     ($32)|CONTROL($  )|  <-   ($1f)|     ($31)|
 ++----+----------------------+------------+------------+------------+------------+------------+------------+------------+------------+
 +</code>
  
base/reading_the_keyboard.txt · Last modified: 2015-04-17 04:33 by 127.0.0.1