; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà
MouseByteNumber DB 0
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ
FirstByte       DB 0
SecondByte      DB 0
ThirdByte       DB 0
timer_ticks_com dd 0
;***************************************
;* ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÌÛØÈ *
;***************************************
check_mouse_data_com1:
;        cmp     [com1_mouse_detected],0
;        je      @@EndMouseInterrupt
; Ïðîâåðèòü íàëè÷èå äàííûõ
        mov     DX,3F8h  ;[COMPortBaseAddr]
        add     DX,5         ;xFDh
        in      AL,DX
        test    AL,1   ;Äàííûå ãîòîâû?
        jz      @@Error
; Ââåñòè äàííûå
        mov     DX,3F8h   ;[COMPortBaseAddr]   ;xF8h
        in      AL,DX
; Ñáðîñèòü ñòàðøèé íåçíà÷àùèé áèò
        and     AL,01111111b

; Îïðåäåëèòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà
        cmp     [MouseByteNumber],0
        je      @@FirstByte
        cmp     [MouseByteNumber],1
        je      @@SecondByte
        cmp     [MouseByteNumber],2
        je      @@ThirdByte
        jmp     @@Error

; Ñîõðàíèòü ïåðâûé áàéò äàííûõ
@@FirstByte:
        test    AL,1000000b       ;Ïåðâûé áàéò ïîñûëêè?
        jz      @@Error
        mov     [FirstByte],AL
        inc     [MouseByteNumber] ;óâåëè÷èòü ñ÷åò÷èê
        jmp     @@EndMouseInterrupt
; Ñîõðàíèòü âòîðîé áàéò äàííûõ
@@SecondByte:
        test    AL,1000000b
        jnz     @@Error
        mov     [SecondByte],AL
        inc     [MouseByteNumber] ;óâåëè÷èòü ñ÷åò÷èê
        jmp     @@EndMouseInterrupt
; Ñîõðàíèòü òðåòèé áàéò äàííûõ
@@ThirdByte:
        test    AL,1000000b
        jnz     @@Error
        mov     [ThirdByte],AL    ;óâåëè÷èòü ñ÷åò÷èê
        mov     [MouseByteNumber],0
; (Ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ).
; Çàïèñàòü íîâîå çíà÷åíèå ñîñòîÿíèÿ êíîïîê ìûøè
        mov al,[FirstByte]   ;[0xfb01]
        mov ah,al
        shr al,3
        and al,2
        shr ah,5
        and ah,1
        add al,ah
        mov    [BTN_DOWN],al
        mov    [mouse_active],1
; Ïðèáàâèòü ïåðåìåùåíèå ïî X ê êîîðäèíàòå X
        mov     AL,[FirstByte]
        shl     AL,6
        or      AL,[SecondByte]
        cbw
        call    mouse_acceleration_com1
        add     AX,[MOUSE_X]    ;[XCoordinate]
        ; Êóðñîð íå äîëæåí âûõîäèòü çà ëåâóþ èëè
        ; ïðàâóþ ãðàíèöó ýêðàíà
        js      @@X1
        cmp     AX,[ScreenWidth]   ;ScreenLength
        jb      @@X2
        ; Óñòàíîâèòü êîîðäèíàòó X ïî ïðàâîé ãðàíèöå
        mov     AX,[ScreenWidth]   ;ScreenLength-1
        dec     ax
        jmp     @@X2
@@X1:
       ; Óñòàíîâèòü êîîðäèíàòó X ïî ëåâîé ãðàíèöå
        xor     AX,AX
@@X2:
        mov     [MOUSE_X],AX     ;[XCoordinate]
        ; Ïðèáàâèòü ïåðåìåùåíèå ïî Y ê êîîðäèíàòå Y
        mov     AL,[FirstByte]
        and     AL,00001100b
        shl     AL,4
        or      AL,[ThirdByte]
        cbw
        call    mouse_acceleration_com1
        add     AX,[MOUSE_Y]   ;[YCoordinate]
        ; Êóðñîð íå äîëæåí âûõîäèòü çà âåðõíþþ èëè
        ; íèæíþþ ãðàíèöó ýêðàíà
        js      @@Y1
        cmp     AX,[ScreenHeight]  ;ScreenHeigth
        jb      @@Y2
        ; Óñòàíîâèòü êîîðäèíàòó X ïî íèæíåé ãðàíèöå
        mov     AX,[ScreenHeight] ;ScreenHeigth-1
        dec     ax
        jmp     @@Y2
@@Y1:
       ; Óñòàíîâèòü êîîðäèíàòó X ïî âåðõíåé ãðàíèöå
        xor     AX,AX
@@Y2:
        mov     [MOUSE_Y],AX     ;[YCoordinate]
        mov   eax,[timer_ticks]
        mov   [timer_ticks_com],eax
        jmp     @@EndMouseInterrupt

@@Error:
; Ïðîèçîøåë ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò
; ìûøè, îáíóëèòü ñ÷åò÷èê áàéòîâ ïàêåòà äàííûõ
        mov     [MouseByteNumber],0
@@EndMouseInterrupt:
        call  ready_for_next_irq
        ret

mouse_acceleration_com1:
        push    eax
        mov   eax,[timer_ticks]
        sub   eax,[timer_ticks_com]
        cmp   eax,[mouse_delay]
        pop    eax
        ja     @f
        imul  ax,[mouse_speed_factor]
@@:
        ret