;.dseg ;keyboard_shift: .byte 1 ; Bit7=break code ; Bit0=shift ; Bit1=alt ;keyboard_buffer: .byte 1 .cseg .def keyboard_reg_1=r17 ;.def keyboard_reg_2=r17 keyboard_handle_byte: push zl push zh CPI keyboard_reg_1,$E0 ;throw away E0s BREQ keyboard_finish CPI keyboard_reg_1,$F0 BREQ keyboard_break_code CPI keyboard_reg_1,$12 ;left shift BREQ keyboard_shiftkey CPI keyboard_reg_1,$59 ;right shift BREQ keyboard_shiftkey CPI keyboard_reg_1,$11 ;alt BREQ keyboard_altkey LDI zl,low(keycode_table*2) LDI zh,high(keycode_table*2) ADD zl,keyboard_reg_1 LDS keyboard_reg_1,keyboard_shift ANDI keyboard_reg_1,$03 ADC zh,keyboard_reg_1 LDS keyboard_reg_1,keyboard_shift SBRS keyboard_reg_1,7 ;skip if not break code RJMP keyboard_unbreak LPM keyboard_reg_1,Z STS keyboard_buffer,keyboard_reg_1 keyboard_unbreak: ;unset the break code LDS keyboard_reg_1,keyboard_shift ANDI keyboard_reg_1,$7f; STS keyboard_shift,keyboard_reg_1 keyboard_finish: pop zh pop zl rjmp keyboard_key_irq_handler_back keyboard_shiftkey: LDS keyboard_reg_1,keyboard_shift ANDI keyboard_reg_1,$fe ;reset shift flag SBRS keyboard_reg_1,7 ;skip if break code ORI keyboard_reg_1,1 ;set shift flag STS keyboard_shift,keyboard_reg_1 rjmp keyboard_finish keyboard_altkey: LDS keyboard_reg_1,keyboard_shift ANDI keyboard_reg_1,$ff-2 ;reset alt flag SBRS keyboard_reg_1,7 ;skip if break code ORI keyboard_reg_1,2 ;set alt flag STS keyboard_shift,keyboard_reg_1 rjmp keyboard_finish keyboard_break_code: ;set flag for making a break code LDS keyboard_reg_1,keyboard_shift ORI keyboard_reg_1,$80; STS keyboard_shift,keyboard_reg_1 rjmp keyboard_finish ;Keyboard routines .equ kf1=128 .equ kf2=129 .equ kf3=130 .equ kf4=131 .equ kf5=132 .equ kf6=133 .equ kf7=134 .equ kf8=135 .equ kf9=136 .equ kf10=137 .equ kf11=138 .equ kf12=139 .equ kesc=27 .equ kret=10;;;;;;;;;;; .equ ktab=9 .equ kbsp=8 .equ kup=24 .equ kdown=25 .equ kleft=28 .equ kright=26 .equ kshift=1 .equ kalt=2 .equ kctr=3 .equ kcaps=4 .equ knum=5 .equ kscr=6 keyboard_key_irq_handler: PUSH keyboard_reg_1 IN keyboard_reg_1,SREG PUSH keyboard_reg_1 keyboard_key_irq_handler_start: in keyboard_reg_1,UDR rjmp keyboard_handle_byte keyboard_key_irq_handler_back: sbic UCSRA,RXC ;still bytes in buffer? rjmp keyboard_key_irq_handler_start ;if yes do it again POP keyboard_reg_1 OUT SREG,keyboard_reg_1 POP keyboard_reg_1 reti keyboard_init: PUSH keyboard_reg_1 ;init buffers LDI keyboard_reg_1,0 STS keyboard_shift,keyboard_reg_1 STS keyboard_buffer,keyboard_reg_1 ;init usart for keyboard LDI keyboard_reg_1,$00 ; U2x=0 OUT UCSRA,keyboard_reg_1 LDI keyboard_reg_1,(1<', 0 , 0 , 0, 0 ,kbsp, 0, 0, '!', 0 ,kleft,'7', 0 , 0 , 0 ;6 .db '0', $2c,kdown,'5',kright,kup,kesc,knum,kf11,'+', $15, '_', '*', '9',kscr, 0 ;7 .db 0 , 0 , 0, kf7, 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;8 ;empty space 128-16 bytes .org keycodes_normal+128*2 keycodes_alt: ; 0 1 2 3 4 5 6 7 8 9 A B C D E F .db 0, kf9, 0, kf5, kf3,kf1, kf2, kf12, 0, kf10,kf8, kf6, kf4, ktab,'^', 0 ;0 .db 0, kalt,kshift,0, kctr,'@', '!', 0, 0, 0, 'Y', 'S', 'A', 'W', $22, 0 ;1 .db 0, 'C', 'X', 'D', 'E', $24, $15, 0, 0, ' ', 'V', 'F', 'T', 'R', $25, 0 ;2 .db 0, 'N', 'B', 'H', 'G', 'Z', '&', 0, 0, 0, 'M', 'J', 'U', '{', '[', 0 ;3 .db 0, $3B, 'K', 'I', 'O', '}', ']', 0, 0, $3A, $22, 'L', $d6, 'P', '\', 0 ;4 .db 0, 0, $c4 , 0, $dc, $62, 0 , 0,kcaps,kshift,kret,'~', 0, $27, 0 , 0 ;5 .db 0, '|', 0 , 0 , 0, 0 ,kbsp, 0, 0, '!', 0 ,kleft,'7', 0 , 0 , 0 ;6 .db '0', $2c,kdown,'5',kright,kup,kesc,knum,kf11,'+', $15, '_', '~', '9',kscr, 0 ;7 .db 0 , 0 , 0, kf7, 0 , 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;8