- .EQU    KEY_ESC         =$76 
- .EQU    KEY_ENTER       =$5A 
- .EQU    KEY_UP          =$75 
- .EQU    KEY_DOWN        =$72 
- .EQU    KEY_LEFT        =$6B 
- .EQU    KEY_RIGHT       =$74 
- .EQU    KEY_PAGEUP      =$7D 
- .EQU    KEY_PAGEDOWN    =$7A 
- .EQU    KEY_HOME        =$6C 
- .EQU    KEY_END         =$69 
- .EQU    KEY_SPACE       =$29 
- .EQU    KEY_F1          =$05 
- .EQU    KEY_NUMLOCK     =$77 
- .EQU    KEY_CAPSLOCK    =$58 
- .EQU    KEY_SCROLLLOCK  =$7E 
- .EQU    KEY_Y           =$35 
-   
- .EQU    PS2K_BIT_PARITY =0 
- .EQU    PS2K_BIT_EXTKEY =1      ; расш.код 
- .EQU    PS2K_BIT_RELEASE=2      ; отпускание 
- .EQU    PS2K_BIT_ACKBIT =3      ; окончание передачи 
- .EQU    PS2K_BIT_TX     =7      ; передача 
- .EQU    PS2K_BIT_READY  =7 
-   
- .MACRO  PS2K_DATALINE_UP 
-         CBI     DDRD,6 
-         SBI     PORTD,6 
- .ENDMACRO 
-   
- .MACRO  PS2K_DATALINE_DOWN 
-         CBI     PORTD,6 
-         SBI     DDRD,6 
- .ENDMACRO 
-   
- .MACRO  PS2K_CLOCKLINE_UP 
-         CBI     DDRE,4 
-         SBI     PORTE,4 
- .ENDMACRO 
-   
- .MACRO  PS2K_CLOCKLINE_DOWN 
-         CBI     PORTE,4 
-         SBI     DDRE,4 
- .ENDMACRO 
- ; 
- ;-------------------------------------- 
- ; 
- .DSEG 
- PS2K_BIT_COUNT: .BYTE   1 
- PS2K_DATA:      .BYTE   1 
- PS2K_RAW_READY: .BYTE   1 
- PS2K_RAW_CODE:  .BYTE   1 
- PS2K_SKIP:      .BYTE   1 
- PS2K_FLAGS:     .BYTE   1 
- PS2K_KEY_FLAGS: .BYTE   1 
- PS2K_KEY_CODE:  .BYTE   1 
- PS2K_TIMEOUT:   .BYTE   2 
- .CSEG 
- ; 
- ;-------------------------------------- 
- ; 
- PS2K_INIT: 
-   
-         IN      TEMP,EICRB 
-         ORI     TEMP,(1<<ISC41)|(0<<ISC40) 
-         OUT     EICRB,TEMP 
-         IN      TEMP,EIMSK 
-         ORI     TEMP,(1<<INT4) 
-         OUT     EIMSK,TEMP 
-   
-         LDI     TEMP,(0<<CS02)|(1<<CS01)|(0<<CS00) ; clk/8 
-         OUT     TCCR0,TEMP 
-   
-         STS     PS2K_FLAGS,NULL 
-         STS     PS2K_BIT_COUNT,NULL 
-         STS     PS2K_SKIP,NULL 
-         STS     PS2K_KEY_FLAGS,NULL 
-   
-         RET 
- ; 
- ;-------------------------------------- 
- ; 
- TIM0_OVF: 
-         PS2K_DATALINE_UP 
-         PUSH    TEMP 
-         IN      TEMP,SREG 
-         PUSH    TEMP 
-         IN      TEMP,TIMSK 
-         CBR     TEMP,(1<<TOIE0) 
-         OUT     TIMSK,TEMP 
-         POP     TEMP 
-         OUT     SREG,TEMP 
-         POP     TEMP 
-         PS2K_CLOCKLINE_UP 
-         RETI 
- ; 
- ;-------------------------------------- 
- ; 
- EXT_INT4: 
-         PUSH    TEMP 
-         IN      TEMP,SREG 
-         PUSH    TEMP 
-         PUSH    COUNT 
-         PUSH    DATA 
-         LDS     DATA,PS2K_DATA 
-         LDS     COUNT,PS2K_BIT_COUNT 
-         LDS     TEMP,PS2K_FLAGS 
-         SBRC    TEMP,PS2K_BIT_TX 
-         RJMP    INT4TX_0 
-   
-         CPI     COUNT,9 
-         BREQ    INT4RX9 
-         CPI     COUNT,10 
-         BRCC    INT4RXS 
-         TST     COUNT 
-         BRNE    INT4RX1 
- ;start bit 
-         SBIC    PIND,6   ; data line 
-         RJMP    INT4RX_CLR_D 
-         CBR     TEMP,(1<<PS2K_BIT_PARITY) 
-         INC     COUNT 
-         RJMP    INT4_EXIT 
- ;data bits 
- INT4RX1:LSR     DATA 
-         SBIS    PIND,6   ; data line 
-         RJMP    INT4RX2 
-         ORI     DATA,0B10000000 
-         EOR     TEMP,ONE 
- INT4RX2:INC     COUNT 
-         RJMP    INT4_EXIT 
- ;parity bit 
- INT4RX9:SBIC    PIND,6   ; data line 
-         EOR     TEMP,ONE 
-         SBRS    TEMP,PS2K_BIT_PARITY 
-         RJMP    INT4RX_CLR_D 
-         INC     COUNT 
-         RJMP    INT4_EXIT 
- ;stop bit 
- INT4RXS:SBIS    PIND,6   ; data line 
-         RJMP    INT4RX_CLR_D 
-   
-         STS     PS2K_RAW_READY,COUNT 
-         STS     PS2K_RAW_CODE,DATA 
-         PS2K_CLOCKLINE_DOWN 
-         LDI     COUNT,$80 
-         OUT     TCNT0,COUNT     ;Tclk*8*128=~92us 
-         LDI     COUNT,(1<<TOV0) 
-         OUT     TIFR,COUNT 
-         IN      COUNT,TIMSK 
-         ORI     COUNT,(1<<TOIE0) 
-         OUT     TIMSK,COUNT 
-   
-         LDS     COUNT,PS2K_SKIP 
-         TST     COUNT 
-         BRNE    INT4RX_SKIP 
-   
-         CPI     DATA,$E1 
-         BREQ    INT4RX_E1 
-         CPI     DATA,$AA 
-         BREQ    INT4RX_CLR_F 
-         CPI     DATA,$AB 
-         BREQ    INT4RX_AB 
-         CPI     DATA,$EE 
-         BREQ    INT4RX_CLR_F 
-         CPI     DATA,$FA 
-         BREQ    INT4RX_CLR_F 
-         CPI     DATA,$FE 
-         BREQ    INT4RX_CLR_F 
-         CPI     DATA,$E0 
-         BREQ    INT4RX_E0 
-         CPI     DATA,$F0 
-         BREQ    INT4RX_F0 
-   
-         SBR     TEMP,(1<<PS2K_BIT_READY) 
-         STS     PS2K_KEY_FLAGS,TEMP 
-         STS     PS2K_KEY_CODE,DATA 
-         RJMP    INT4RX_CLR_F 
-   
- INT4RX_E0: 
-         SBR     TEMP,(1<<PS2K_BIT_EXTKEY) 
-         RJMP    INT4RX_CLR_D 
-   
- INT4RX_F0: 
-         SBR     TEMP,(1<<PS2K_BIT_RELEASE) 
-         RJMP    INT4RX_CLR_D 
-   
- INT4RX_SKIP: 
-         DEC     COUNT 
-         STS     PS2K_SKIP,COUNT 
-         BRNE    INT4RX_CLR_D 
-         LDS     DATA,PS2K_KEY_CODE 
-         CPI     DATA,$7E 
-         BRNE    INT4RX_CLR_D 
-         LDI     TEMP,(1<<PS2K_BIT_READY)|(1<<PS2K_BIT_RELEASE)|(1<<PS2K_BIT_EXTKEY) 
-         STS     PS2K_KEY_FLAGS,TEMP 
-         RJMP    INT4RX_CLR_F 
-   
- INT4RX_AB: 
-         STS     PS2K_KEY_CODE,NULL 
-         LDI     COUNT,1 
-         STS     PS2K_SKIP,COUNT 
-         RJMP    INT4RX_CLR_F 
-   
- INT4RX_E1: 
-         LDI     TEMP,(1<<PS2K_BIT_READY)|(1<<PS2K_BIT_EXTKEY) 
-         STS     PS2K_KEY_FLAGS,TEMP 
-         LDI     DATA,$7E 
-         STS     PS2K_KEY_CODE,DATA 
-         LDI     COUNT,7 
-         STS     PS2K_SKIP,COUNT 
-   
- INT4RX_CLR_F: 
-         CLR     TEMP 
- INT4RX_CLR_D: 
-         CLR     DATA 
-         CLR     COUNT 
-         RJMP    INT4_EXIT 
- ;------- 
- INT4TX_0: 
-         CPI     COUNT,9 
-         BREQ    INT4TX9 
-         CPI     COUNT,10 
-         BREQ    INT4TXS 
-         CPI     COUNT,11 
-         BRCC    INT4TXA 
-         TST     COUNT 
-         BRNE    INT4TX1 
- ;start bit 
-         SBR     TEMP,(1<<PS2K_BIT_PARITY) 
-         INC     COUNT 
-         RJMP    INT4_EXIT 
- ;data bits 
- INT4TX1:ROR     DATA 
-         BRCC    INT4TX2 
-         PS2K_DATALINE_UP 
-         EOR     TEMP,ONE 
-         INC     COUNT 
-         RJMP    INT4_EXIT 
- INT4TX2:PS2K_DATALINE_DOWN 
-         INC     COUNT 
-         RJMP    INT4_EXIT 
- ;parity bit 
- INT4TX9:SBRC    TEMP,PS2K_BIT_PARITY 
-         RJMP    INT4TXP 
-         PS2K_DATALINE_DOWN 
-         INC     COUNT 
-         RJMP    INT4_EXIT 
- INT4TXP:PS2K_DATALINE_UP 
-         INC     COUNT 
-         RJMP    INT4_EXIT 
- ;stop bit 
- INT4TXS:PS2K_DATALINE_UP 
-         INC     COUNT 
-         RJMP    INT4_EXIT 
- ;здесь раньше проверялся ack-bit, но CHRV знает ;) 
- ; где есть такие клавиатуры, которые не выдают этот бит. 
- INT4TXA:;CLR     TEMP 
-         ;SBIS    PIND,6   ; data line 
-         LDI     TEMP,(1<<PS2K_BIT_ACKBIT) 
-         CLR     DATA 
-         CLR     COUNT 
-   
- INT4_EXIT: 
-         STS     PS2K_BIT_COUNT,COUNT 
-         STS     PS2K_DATA,DATA 
-         STS     PS2K_FLAGS,TEMP 
-         POP     DATA 
-         POP     COUNT 
-         POP     TEMP 
-         OUT     SREG,TEMP 
-         POP     TEMP 
-         RETI 
- ; 
- ;-------------------------------------- 
- ;out:   DATA == скан-код клавиши 
- ;       TEMP.PS2K_BIT_EXTKEY == расш.код 
- WAITKEY:CALL    RANDOM 
-         LDS     TEMP,PS2K_KEY_FLAGS 
-         SBRS    TEMP,PS2K_BIT_READY 
-         RJMP    WAITKEY 
-         STS     PS2K_KEY_FLAGS,NULL 
-         SBRC    TEMP,PS2K_BIT_RELEASE 
-         RJMP    WAITKEY 
-         LDS     DATA,PS2K_KEY_CODE 
-         RET 
- ; 
- ;-------------------------------------- 
- ;out:   sreg.Z == clr - было нажатие (автоповтор) 
- ;       DATA == скан-код клавиши 
- ;       TEMP.PS2K_BIT_EXTKEY == расш.код 
- INKEY:  CALL    RANDOM 
-         LDS     TEMP,PS2K_KEY_FLAGS 
-         SBRS    TEMP,PS2K_BIT_READY 
-         RJMP    INKEY9 
-         STS     PS2K_KEY_FLAGS,NULL 
-         SBRC    TEMP,PS2K_BIT_RELEASE 
-         RJMP    INKEY9 
-         LDS     DATA,PS2K_KEY_CODE 
-         CLZ 
-         RET 
-   
- INKEY9: SEZ 
-         RET 
- ; 
- ;-------------------------------------- 
- ;in:    DATA 
- ;out:   sreg.Z - CLR == ok; SET == timeout 
- PS2K_SEND_BYTE: 
-         PS2K_DATALINE_UP 
-         IN      TEMP,TIMSK 
-         CBR     TEMP,(1<<TOIE0) 
-         OUT     TIMSK,TEMP 
-         PS2K_CLOCKLINE_UP 
-         CLR     TEMP 
- PS2K_SEND0: 
-         SBIS    PINE,4   ; clock line 
-         RJMP    PS2K_SEND_BYTE 
-         DEC     TEMP 
-         BRNE    PS2K_SEND0 
-   
-         CLI 
-         PS2K_CLOCKLINE_DOWN 
-         PS2K_DATALINE_DOWN 
-         STS     PS2K_DATA,DATA 
-         LDI     TEMP,(1<<PS2K_BIT_TX) 
-         STS     PS2K_FLAGS,TEMP 
-         STS     PS2K_BIT_COUNT,NULL 
-         STS     PS2K_SKIP,NULL 
-         STS     PS2K_KEY_FLAGS,NULL 
-         STS     PS2K_RAW_READY,NULL 
-         SEI 
-         DELAY_US 100 
-         PS2K_DATALINE_DOWN 
-         DELAY_US 500 
-         LDIZ    PS2K_TIMEOUT 
-         LDIW    15 
-         CALL    SET_TIMEOUT_MS 
-         PS2K_CLOCKLINE_UP 
- PS2K_SEND1: 
-         LDS     TEMP,PS2K_FLAGS 
-         ANDI    TEMP,(1<<PS2K_BIT_ACKBIT) 
-         BRNE    PS2K_SEND2 
-         LDIZ    PS2K_TIMEOUT 
-         CALL    CHECK_TIMEOUT_MS 
-         BRCC    PS2K_SEND1 
-         PS2K_DATALINE_UP 
-         SEZ 
- PS2K_SEND2: 
-         RET 
- ; 
- ;-------------------------------------- 
- ;out:   sreg.Z - CLR == ok; SET == timeout 
- ;       DATA == byte 
- PS2K_RECEIVE_BYTE: 
-         STS     PS2K_RAW_READY,NULL 
-         LDIZ    PS2K_TIMEOUT 
-         LDIW    20 
-         CALL    SET_TIMEOUT_MS 
-   
- PS2K_RXBYTE1: 
-         LDS     TEMP,PS2K_RAW_READY 
-         TST     TEMP 
-         BRNE    PS2K_RXBYTE2 
-         LDIZ    PS2K_TIMEOUT 
-         CALL    CHECK_TIMEOUT_MS 
-         BRCC    PS2K_RXBYTE1 
-         CLR     DATA 
-         SEZ 
-         RET 
-   
- PS2K_RXBYTE2: 
-         LDS     DATA,PS2K_RAW_CODE 
-         RET 
- ; 
- ;-------------------------------------- 
- ; 
- .EQU    PS2K_DETECT_TEMP=0 
- ; 
- PS2K_DETECT_KBD: 
-         GETMEM  1 
-         PS2K_CLOCKLINE_UP 
-         LDIZ    MLMSG_KBD_DETECT*2 
-         RCALL   PRINTMLSTR 
-   
-         STS     PS2K_RAW_READY,NULL 
-         LDIZ    PS2K_TIMEOUT 
-         LDIW    500 
-         CALL    SET_TIMEOUT_MS 
- PS2K_DETECT_K1: 
-         LDS     TEMP,PS2K_RAW_READY 
-         TST     TEMP 
-         BRNE    PS2K_DETECT_K2 
-         LDIZ    PS2K_TIMEOUT 
-         CALL    CHECK_TIMEOUT_MS 
-         BRCC    PS2K_DETECT_K1 
-         RJMP    PS2K_DETECT_K3 
- PS2K_DETECT_K2: 
-         LDS     DATA,PS2K_RAW_CODE 
-         RCALL   HEXBYTE_FOR_DUMP 
- PS2K_DETECT_K3: 
-   
-         LDI     DATA,$FF 
-         RCALL   PS2K_DETECT_SEND 
- ;        BRNE    PS2K_DETECT_K6 
-         STS     PS2K_RAW_READY,NULL 
-         LDIZ    PS2K_TIMEOUT 
-         LDIW    1000 
-         CALL    SET_TIMEOUT_MS 
- PS2K_DETECT_K4: 
-         LDS     TEMP,PS2K_RAW_READY 
-         TST     TEMP 
-         BRNE    PS2K_DETECT_K5 
-         LDIZ    PS2K_TIMEOUT 
-         CALL    CHECK_TIMEOUT_MS 
-         BRCC    PS2K_DETECT_K4 
-         RCALL   PS2K_DETECT_NORESPONSE 
-         RJMP    PS2K_DETECT_K6 
- PS2K_DETECT_K5: 
-         LDS     DATA,PS2K_RAW_CODE 
-         RCALL   HEXBYTE_FOR_DUMP 
-         CPI     DATA,$AA 
-         BREQ    PS2K_DETECT_K6 
-         RCALL   PS2K_DETECT_UNWANTED 
-   
- PS2K_DETECT_K6: 
-         LDI     DATA,$F2 
-         RCALL   PS2K_DETECT_SEND 
-         BRNE    PS2K_DETECT_K7 
-         LDI     DATA,$AB 
-         RCALL   PS2K_DETECT_RECEIVE 
-         BRNE    PS2K_DETECT_K7 
-         LDI     DATA,$83 
-         RCALL   PS2K_DETECT_RECEIVE 
- PS2K_DETECT_K7: 
-         LDI     DATA,$F0 
-         RCALL   PS2K_DETECT_SEND 
-         BRNE    PS2K_DETECT_K8 
-         LDI     DATA,$02 
-         RCALL   PS2K_DETECT_SEND 
- PS2K_DETECT_K8: 
-         LDI     DATA,$F3 
-         RCALL   PS2K_DETECT_SEND 
-         BRNE    PS2K_DETECT_K9 
-         LDI     DATA,$00 
-         RCALL   PS2K_DETECT_SEND 
-         LDIZ    MSG_READY*2+3 
-         CALL    PRINTSTRZ 
- PS2K_DETECT_K9: 
-         FREEMEM 1 
-         RET 
- ; 
- PS2K_DETECT_SEND: 
-         RCALL   HEXBYTE_FOR_DUMP 
-         RCALL   PS2K_SEND_BYTE 
-         BREQ    PS2K_DETECT_TXFAIL 
-         RCALL   PS2K_RECEIVE_BYTE 
-         BREQ    PS2K_DETECT_NORESPONSE 
-         RCALL   HEXBYTE_FOR_DUMP 
-         CPI     DATA,$FA 
-         BRNE    PS2K_DETECT_UNWANTED 
-         RET 
- ; 
- PS2K_DETECT_RECEIVE: 
-         STH     PS2K_DETECT_TEMP,DATA 
-         RCALL   PS2K_RECEIVE_BYTE 
-         BREQ    PS2K_DETECT_NORESPONSE 
-         RCALL   HEXBYTE_FOR_DUMP 
-         LDH     TEMP,PS2K_DETECT_TEMP 
-         CP      DATA,TEMP 
-         BRNE    PS2K_DETECT_UNWANTED 
-         RET 
- ; 
- PS2K_DETECT_TXFAIL: 
-         LDIZ    MLMSG_TXFAIL*2 
-         RJMP    PS2K_DETECT_XXFAIL 
- PS2K_DETECT_UNWANTED: 
-         LDIZ    MLMSG_UNWANTED*2 
-         RJMP    PS2K_DETECT_XXFAIL 
- PS2K_DETECT_NORESPONSE: 
-         LDIZ    MLMSG_NORESPONSE*2 
- PS2K_DETECT_XXFAIL: 
-         CALL    PRINTMLSTR 
-         CLZ 
-         RET 
- ; 
- ;-------------------------------------- 
- ; 
-