; Номер принимаемого от мыши байта MouseByteNumber_2 DB 0 ; Трехбайтовая структура данных, передаваемая мышью FirstByte_2 DB 0 SecondByte_2 DB 0 ThirdByte_2 DB 0 timer_ticks_ps2 dd 0 ;************************************** ;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ МЫШИ PS/2 * ;************************************** check_mouse_data_ps2: cmp [ps2_mouse_detected],0 je @@EndMouseInterrupt_2 call Wait8042BufferEmpty ;очистка буфера in AL,0x60 ;получить скэн-код ; Выбирать порядковый номер принимаемого байта cmp [MouseByteNumber_2],0 je @@SaveFirstByte cmp [MouseByteNumber_2],1 je @@SaveSecondByte cmp [MouseByteNumber_2],2 je @@SaveThirdByte jmp @@Error_2 ; Записать первый байт посылки @@SaveFirstByte: test AL,1000b ;первый байт посылки? jz @@Error_2 ;сбой синхронизации mov [FirstByte_2],AL inc [MouseByteNumber_2] jmp @@EndMouseInterrupt_2 ; Записать второй байт посылки @@SaveSecondByte: mov [SecondByte_2],AL inc [MouseByteNumber_2] jmp @@EndMouseInterrupt_2 ; Записать третий байт посылки @@SaveThirdByte: mov [ThirdByte_2],AL mov [MouseByteNumber_2],0 ; (пакет данных от мыши принят полностью) ; Записать новое значение байта состояния кнопок mov al,[FirstByte_2] ;[0xfb01] and eax,3 mov [0xfb40],al mov [mouse_active],1 ; Вычислить новую X-координату курсора ; Занести в AX перемещение по X mov AH,0 ;дублируем знак во все разряды AH mov AL,[FirstByte_2] test AL,10000b jz @@M0 mov AH,0FFh ; Занести в AL младший байт @@M0: mov AL,[SecondByte_2] call mouse_acceleration_ps2 ; Вычислить новое значение координаты ; курсора по X add AX,[0xFB0A] ;[XCoordinate] cmp AX,0 jge @@M1 mov AX,0 jmp @@M2 @@M1: cmp AX,[0xFE00] ;ScreenLength jl @@M2 mov AX,[0xFE00] ;ScreenLength-1 dec ax @@M2: mov [0xFB0A],AX ;[XCoordinate] ; Вычисляем новую Y-координату курсора ; Занести в AX перемещение по Y mov AH,0 ;дублируем знак во все разряды AH mov AL,[FirstByte_2] test AL,100000b jz @@M3 mov AH,0FFh ; Занести в AL младший байт @@M3: mov AL,[ThirdByte_2] call mouse_acceleration_ps2 ; Вычислить новое значение координаты курсора ; по Y (Y-координата мыши PS/2 направлена ; противоположно экранной) neg AX add AX,[0xFB0C] ;[YCoordinate] cmp AX,0 jge @@M4 mov AX,0 jmp @@M5 @@M4: cmp AX,[0xFE04] ;ScreenHeigth jl @@M5 mov AX,[0xFE04] ;ScreenHeigth-1 dec ax @@M5: mov [0xFB0C],AX ;[YCoordinate] ; Показать курсор в новой позиции mov eax,[timer_ticks] mov [timer_ticks_ps2],eax jmp @@EndMouseInterrupt_2 ; Обнаружен сбой в порядке передачи информации от мыши @@Error_2: mov [MouseByteNumber_2],0 ; Нормальное завершение прерывания @@EndMouseInterrupt_2: call ready_for_next_irq_1 ret mouse_acceleration_ps2: push eax mov eax,[timer_ticks] sub eax,[timer_ticks_ps2] cmp eax,[mouse_delay] pop eax ja @f imul ax,[mouse_speed_factor] @@: ret ;*********************************************** ;* ОЖИДАНИЕ ОЧИСТКИ ВХОДНОГО БУФЕРА I8042 * ;* При выходе из процедуры: * ;* флаг ZF установлен - нормальное завершение, * ;* флаг ZF сброшен - ошибка тайм-аута. * ;*********************************************** Wait8042BufferEmpty: ; push CX ; mov CX,0FFFFh ;задать число циклов ожидания ;@@kb: ; in AL,64h ;получить статус ; test AL,10b ;буфер i8042 свободен? ; loopnz @@kb ;если нет, то цикл ; pop CX push ecx xor ecx,ecx @@: in al,64h test al,00000010b loopnz @b pop ecx ;Если при выходе из подпрограммы сброшен ;флаг ZF - ошибка ret ;возврат в подпрограмму ;*************************************** ;* ОЖИДАНИЕ ПОСТУПЛЕНИЯ ДАННЫХ ОТ МЫШИ * ;*************************************** WaitMouseData: ; push CX ; mov CX,0FFFFh ;задать число циклов ожидания ;@@mouse: ; in AL,64h ;опросить регистр статуса ; test AL,100000b ;данные поступили? ; loopz @@mouse ;если нет, то цикл ; pop CX push ecx mov ECX,0FFFFh @@: in al,64h test al,100000b loopz @b pop ecx ;Если при выходе из подпрограммы установлен ;флаг ZF - ошибка ret