+----+----------------------+--------------------------------------------------- ----------------------------------------------------+ | | | Peek from $dc01 (code in paranthesis): | |row:| $dc00: +------------+------------+------------+------------+------------+------------+- -----------+------------+ | | | BIT 8 | BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | +----+----------------------+------------+------------+------------+------------ +------------+------------+------------+------------+ |1. | #%11111110 (254/$fe) | DOWN ($ )| F5 ($ )| F3 ($ )| F1 ($ )| F7 ($ )| RIGHT ($ )| RETURN($ )|DELETE ($ )| |2. | #%11111101 (253/$fd) |LEFT-SH($ )| e ($05)| s ($13)| z ($1a)| 4 ($34)| a ($01)| w ($17)| 3 ($33)| |3. | #%11111011 (251/$fb) | x ($18)| t ($14)| f ($06)| c ($03)| 6 ($36)| d ($04)| r ($12)| 5 ($35)| |4. | #%11110111 (247/$f7) | v ($16)| u ($15)| h ($08)| b ($02)| 8 ($38)| g ($07)| y ($19)| 7 ($37)| |5. | #%11101111 (239/$ef) | n ($0e)| o ($0f)| k ($0b)| m ($0d)| 0 ($30)| j ($0a)| i ($09)| 9 ($39)| |6. | #%11011111 (223/$df) | , ($2c)| @ ($00)| : ($3a)| . ($2e)| - ($2d)| l ($0c)| p ($10)| + ($2b)| |7. | #%10111111 (191/$bf) | / ($2f)| ^ ($1e)| = ($3d)|RGHT-SH($ )| HOME ($ )| ; ($3b)| * ($2a)| £ ($1c)| |8. | #%01111111 (127/$7f) | STOP ($ )| q ($11)|COMMODR($ )| SPACE ($20)| 2 ($32)|CONTROL($ )| <- ($1f)| 1 ($31)| +----+----------------------+------------+------------+------------+------------ +------------+------------+------------+------------+
minikey: lda #$0 sta $dd03 ; port b ddr (input) lda #$ff sta $dd02 ; 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
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
.macro KBCheckKey key ;Returns zero if the checked key is pressed ldy #<(key) ;Keyboard matrix row number in Y lda #>(key) ;Keyboard matrix row value for given key in A and KBMatrixSnapShot,y ;Check given key value against row value in matrix .endmacro ;If equal, Zero flag is cleared .macro KBCheckKeyDown key ;Returns zero if the checked key has a Key Down event ldy #<(key) ;Keyboard matrix row number in Y lda #>(key) ;Keyboard matrix row value for given key in A and KBMatrixKeyDown,y ;Check given key value against row value in matrix .endmacro ;If equal, Zero flag is cleared .macro KBCheckKeyUp key ;Returns zero if the checked key has a Key Up event ldy #<(key) ;Keyboard matrix row number in Y lda #>(key) ;Keyboard matrix row value for given key in A and KBMatrixKeyUp,y ;Check given key value against row value in matrix .endmacro ;If equal, Zero flag is cleared .macro KBAckEvents ;Acknowledge all Key Up/Down events lda #$01 ora KBMSG sta KBMSG .endmacro
KEY_F3 = $2000 ;.byte %00100000,0 KEY_F5 = $4000 ;.byte %01000000,0 KEY_CRSRUD = $8000 ;.byte %10000000,0 KEY_3 = $0101 ;.byte %00000001,1 KEY_W = $0201 ;.byte %00000010,1 KEY_A = $0401 ;.byte %00000100,1
You can use this feature to distinquish between the left shift and the shift lock keys, although they are connected to same hardware lines. The shift lock key has smaller resistance than the left shift. If you make both CIA 1 ports to outputs (write $FF to $DC03 and $DC01) prior reading the left shift key, only shift lock can change the values you read from CIA 1 port B ($DC01).)
This happens in VICE btw, and on other row/column combinations as well.
zp_keyboard_current = $10 ;zeropage keycode buffer ldy #((continue_key-get_kb_column+1) ^ 255) sty continue_key+1 ldy #$40 lda #%11111101 sta $dc00 lda $dc01 and #%10000000 beq shifted_keys ;left shift pressed lda #%10111111 sta $dc00 lda $dc01 and #%00010000 beq shifted_keys ;right shift pressed ldy #$00 shifted_keys sty get_shifted_chr+1 lda #%01111111 sta cur_key_row+1 ldx #64 next_key_row cur_key_row lda #%01111111 sta $dc00 sec ror cur_key_row+1 txa sbx #8 bcc key_rows_finished lda $dc01 eor #$ff beq next_key_row sta cur_kb_column+1 ldy #7 sty get_kb_column+1 get_kb_column ldy #7 cur_kb_column lda #0 - lsr bcs found_kb_column dey bpl - bmi next_key_row key_rows_finished ldy #((continue_key-buffer_key+1) ^ 255) sty continue_key+1 lda #0 beq buffer_key found_kb_column sta cur_kb_column+1 stx get_kb_char_row+1 tya dey sty get_kb_column+1 get_kb_char_row ora #0 get_shifted_chr ora #0 tay lda keyboard_mapping,y cmp #$fd ;$fd = C=, $fe = shift bcs get_kb_column buffer_key sta zp_keyboard_current inc buffer_key+1 ldy buffer_key+1 cpy #zp_keyboard_current+3 continue_key bcc get_kb_column lda #zp_keyboard_current sta buffer_key+1 keyboard_mapping .byte $ef-$00,$f5-$00,$f3-$00,$f1-$00,$f7-$00,$ec-$00,$e3-$00,$eb-$00 .byte $fe-$00,"E"-$40,"S"-$40,"Z"-$40,"4"-$00,"A"-$40,"W"-$40,"3"-$00 .byte "X"-$40,"T"-$40,"F"-$40,"C"-$40,"6"-$00,"D"-$40,"R"-$40,"5"-$00 .byte "V"-$40,"U"-$40,"H"-$40,"B"-$40,"8"-$00,"G"-$40,"Y"-$40,"7"-$00 .byte "N"-$40,"O"-$40,"K"-$40,"M"-$40,"0"-$00,"J"-$40,"I"-$40,"9"-$00 .byte ","-$00,"@"-$00,":"-$00,"."-$00,$e8-$00,"L"-$40,"P"-$40,$e9-$00 .byte "/"-$00,$ff-$00,"="-$00,$fe-$00,$ff-$00,";"-$00,"*"-$00,$ff-$00 .byte $fc-$00,"Q"-$40,$ff-$00,$20-$00,"2"-$00,$e7-$00,$f0-$00,"1"-$00 keyboard_mapping_shifted .byte $ed-$00,$f6-$00,$f4-$00,$f2-$00,$f8-$00,$ee-$00,$e3-$00,$ea-$00 .byte $fe-$00,"E"-$00,"S"-$00,"Z"-$00,"$"-$00,"A"-$00,"W"-$00,"#"-$00 .byte "X"-$00,"T"-$00,"F"-$00,"C"-$00,"&"-$00,"D"-$00,"R"-$00,"%"-$00 .byte "V"-$00,"U"-$00,"H"-$00,"B"-$00,"("-$00,"G"-$00,"Y"-$00,"'"-$00 .byte "N"-$00,"O"-$00,"K"-$00,"M"-$00,"0"-$00,"J"-$00,"I"-$00,")"-$00 .byte $e6-$00,"@"-$00,"["-$00,$e4-$00,$e8-$00,"L"-$00,"P"-$00,$e9-$00 .byte "?"-$00,$ff-$00,"="-$00,$fe-$00,$ff-$00,"]"-$00,"*"-$00,$ff-$00 .byte $fc-$00,"Q"-$00,$ff-$00,$60-$00,'"'-$00,$e5-$00,$f0-$00,"!"-$00
Is there an indication as to why this will give unpredicted results when used on real hardware?
whats the fuss about detecting 3 keys?