Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

#include <avr/io.h>
#include "_ps2k.h"
;
;--------------------------------------
;
.macro  ps2k_dataline_up
        cbi     _SFR_IO_ADDR(DDRD),6
        sbi     _SFR_IO_ADDR(PORTD),6
.endm
;
.macro  ps2k_dataline_down
        cbi     _SFR_IO_ADDR(PORTD),6
        sbi     _SFR_IO_ADDR(DDRD),6
.endm
;
.macro  ps2k_clockline_up
        cbi     _SFR_IO_ADDR(DDRE),4
        sbi     _SFR_IO_ADDR(PORTE),4
.endm
;
.macro  ps2k_clockline_down
        cbi     _SFR_IO_ADDR(PORTE),4
        sbi     _SFR_IO_ADDR(DDRE),4
.endm
;
;--------------------------------------
;
.global TIMER0_OVF_vect
.func TIMER0_OVF_vect
TIMER0_OVF_vect:
        ps2k_dataline_up
        push    r18
        in      r18,_SFR_IO_ADDR(SREG)
        push    r18
        in      r18,_SFR_IO_ADDR(TIMSK)
        cbr     r18,(1<<TOIE0)
        out     _SFR_IO_ADDR(TIMSK),r18
        pop     r18
        out     _SFR_IO_ADDR(SREG),r18
        pop     r18
        ps2k_clockline_up
        reti
.endfunc
;
;--------------------------------------
;
.global INT4_vect
.func INT4_vect
INT4_vect:
        push    r18
        in      r18,_SFR_IO_ADDR(SREG)
        push    r18
        push    r19
        push    r20
        push    r21
        ldi     r21,1
        lds     r19,ps2k_data
        lds     r20,ps2k_bit_count
        lds     r18,ps2k_flags
        sbrc    r18,PS2K_BIT_TX
        rjmp    .L_int4tx_0

        cpi     r20,9
        breq    .L_int4rx9
        cpi     r20,10
        brcc    .L_int4rxs
        tst     r20
        brne    .L_int4rx1
;start bit
        sbic    _SFR_IO_ADDR(PIND),6   ; data line
        rjmp    .L_int4rx_clr_d
        cbr     r18,(1<<PS2K_BIT_PARITY)
        inc     r20
        rjmp    .L_int4_exit
;data bits
.L_int4rx1:
        lsr     r19
        sbis    _SFR_IO_ADDR(PIND),6   ; data line
        rjmp    .L_int4rx2
        ori     r19,0b10000000
        eor     r18,r21
.L_int4rx2:
        inc     r20
        rjmp    .L_int4_exit
;parity bit
.L_int4rx9:
        sbic    _SFR_IO_ADDR(PIND),6   ; data line
        eor     r18,r21
        sbrs    r18,PS2K_BIT_PARITY
        rjmp    .L_int4rx_clr_d
        inc     r20
        rjmp    .L_int4_exit
;stop bit
.L_int4rxs:
        sbis    _SFR_IO_ADDR(PIND),6   ; data line
        rjmp    .L_int4rx_clr_d

        sts     ps2k_raw_ready,r20
        sts     ps2k_raw_code,r19
        ps2k_clockline_down
        ldi     r20,0x80
        out     _SFR_IO_ADDR(TCNT0),r20     ;Tclk*8*128=~92us
        ldi     r20,(1<<TOV0)
        out     _SFR_IO_ADDR(TIFR),r20
        in      r20,_SFR_IO_ADDR(TIMSK)
        ori     r20,(1<<TOIE0)
        out     _SFR_IO_ADDR(TIMSK),r20

        lds     r20,ps2k_skip
        tst     r20
        brne    .L_int4rx_skip

        cpi     r19,0xe1
        breq    .L_int4rx_e1
        cpi     r19,0xaa
        breq    .L_int4rx_clr_f
        cpi     r19,0xab
        breq    .L_int4rx_ab
        cpi     r19,0xee
        breq    .L_int4rx_clr_f
        cpi     r19,0xfa
        breq    .L_int4rx_clr_f
        cpi     r19,0xfe
        breq    .L_int4rx_clr_f
        cpi     r19,0xe0
        breq    .L_int4rx_e0
        cpi     r19,0xf0
        breq    .L_int4rx_f0

        sbr     r18,(1<<PS2K_BIT_READY)
        sts     ps2k_key_flags_and_code,r18
        sts     (ps2k_key_flags_and_code)+1,r19
        rjmp    .L_int4rx_clr_f

.L_int4rx_e0:
        sbr     r18,(1<<PS2K_BIT_EXTKEY)
        rjmp    .L_int4rx_clr_d

.L_int4rx_f0:
        sbr     r18,(1<<PS2K_BIT_RELEASE)
        rjmp    .L_int4rx_clr_d

.L_int4rx_skip:
        dec     r20
        sts     ps2k_skip,r20
        brne    .L_int4rx_clr_d
        lds     r19,(ps2k_key_flags_and_code)+1
        cpi     r19,0x7e
        brne    .L_int4rx_clr_d
        ldi     r18,(1<<PS2K_BIT_READY)|(1<<PS2K_BIT_RELEASE)|(1<<PS2K_BIT_EXTKEY)
        sts     ps2k_key_flags_and_code,r18
        rjmp    .L_int4rx_clr_f

.L_int4rx_ab:
        clr     r19
        sts     (ps2k_key_flags_and_code)+1,r19
        sts     ps2k_skip,r21
        rjmp    .L_int4rx_clr_f

.L_int4rx_e1:
        ldi     r18,(1<<PS2K_BIT_READY)|(1<<PS2K_BIT_EXTKEY)
        sts     ps2k_key_flags_and_code,r18
        ldi     r19,0x7e
        sts     (ps2k_key_flags_and_code)+1,r19
        ldi     r20,7
        sts     ps2k_skip,r20

.L_int4rx_clr_f:
        clr     r18
.L_int4rx_clr_d:
        clr     r19
        clr     r20
        rjmp    .L_int4_exit
;-------
.L_int4tx_0:
        cpi     r20,9
        breq    .L_int4tx9
        cpi     r20,10
        breq    .L_int4txs
        cpi     r20,11
        brcc    .L_int4txa
        tst     r20
        brne    .L_int4tx1
;start bit
        sbr     r18,(1<<PS2K_BIT_PARITY)
        inc     r20
        rjmp    .L_int4_exit
;data bits
.L_int4tx1:
        ror     r19
        brcc    .L_int4tx2
        ps2k_dataline_up
        eor     r18,r21
        inc     r20
        rjmp    .L_int4_exit
.L_int4tx2:
        ps2k_dataline_down
        inc     r20
        rjmp    .L_int4_exit
;parity bit
.L_int4tx9:
        sbrc    r18,PS2K_BIT_PARITY
        rjmp    .L_int4txp
        ps2k_dataline_down
        inc     r20
        rjmp    .L_int4_exit
.L_int4txp:
        ps2k_dataline_up
        inc     r20
        rjmp    .L_int4_exit
;stop bit
.L_int4txs:
        ps2k_dataline_up
        inc     r20
        rjmp    .L_int4_exit
;здесь раньше проверялся ack-bit, но CHRV знает ;)
; где есть такие клавиатуры, которые не выдают этот бит.
.L_int4txa:
        ;clr     r18
        ;sbis    _SFR_IO_ADDR(PIND),6   ; data line
        ldi     r18,(1<<PS2K_BIT_ACKBIT)
        clr     r19
        clr     r20

.L_int4_exit:
        sts     ps2k_bit_count,r20
        sts     ps2k_data,r19
        sts     ps2k_flags,r18
        pop     r21
        pop     r20
        pop     r19
        pop     r18
        out     _SFR_IO_ADDR(SREG),r18
        pop     r18
        reti
.endfunc
;
;--------------------------------------