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?