Работа с мышью в Защищенном режиме

Тема в разделе "WASM.OS.DEVEL", создана пользователем Toxasoft, 27 май 2011.

  1. Toxasoft

    Toxasoft New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2010
    Сообщения:
    188
    Здраствуйте. Подскажите плиз где есть статьи или примеры для поиска и работы с мышью в PM..

    P.S В гугл искал, там один бред по этой теме.
     
  2. Phantom_84

    Phantom_84 New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2007
    Сообщения:
    820
    Ну, например, вот это:
    http://www.computer-engineering.org/ps2mouse/
     
  3. shm

    shm New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2010
    Сообщения:
    93
    Toxasoft, ты не указал самого главного, а именно какого типа у тебя мышь. Для PS/2 Phantom_84 дал ссылку на очень неплохую статью. Если мышь USB, то тут все немножко сложнее, сперва нужно научиться работать с хост-контроллером USB, написать хотя бы примитивный драйвер и потом приступать непосредственно к написанию драйвера мыши. Хотя по моему личному опыту, работать с USB устройствами очень удобно и элементарный драйвер мыши займет всего несколько десятков строк кода при наличии драйвера хост-контроллера. По поводу низкоуровневого программирования USB рекомендую почитать http://forum.sources.ru/index.php?showtopic=113980. Но тут есть и другой подход, если в PM кроме мыши и клавиатуры больше ничего не планируется использовать и БИОС поддерживает Legacy Support, то с USB мышкой или клавиатурой можно работать как с обычными устройствами PS/2 того же типа через стандартные порты, БИОС с помощью SMI будет производить эмуляцию совершенно прозрачно для твоей программы или ОС в защищенном режиме.
     
  4. shm

    shm New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2010
    Сообщения:
    93
    PS/2 мышь и клавиатура управляются i8042 совместимым контроллером и общий принцип работы с ними очень похож. Только в отличии от клавиатуры никто не гарантирует, что мышь PS/2 будет инициализирована после процедур БИОСа, поэтому это надо делать самому, а именно разрешить работу с ней и прерывание. ЕМНИП, то конкретно для самой простой инициализации достаточно просто послать команду "разрешить передачу данных" и "установить потоковый режим". Для записи/чтения в регистр команд i8042 используются команды 0x60 и 0x10 соответственно, формат его легко гуглится http://forum.codenet.ru/archive/index.php/t-1193.html впрочем как и все остальное. Для передачи мыши данных используется команда 0xD4. Все команды записываются в порт 0x60 (ответы на них считываются оттуда же), для синхронизации всего этого дела служит регистр состояния 0x64 http://wikihardware.ru/index.php?option=com_content&view=article&id=209:_interfeys_klaviaturi&catid=13:_videosistema&Itemid=14 . И конечно не стоит забывать считывать ACK после подачи команды, в противном случае на многих чипсетах драйвер работать не будет, а на некоторых вообще может привести к зависанию.
     
  5. Toxasoft

    Toxasoft New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2010
    Сообщения:
    188
    Спасибо буду пробовать. А мышь пока PS\2.
     
  6. Toxasoft

    Toxasoft New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2010
    Сообщения:
    188
    Здесь такая вот фигня вышла: с инициализацией разобрался, а вот с обработчиком прерывания не могу....
    Дайте плиз пример обработчика....
     
  7. dinoweb

    dinoweb Дмитрий

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    129
    Адрес:
    Россия. Красноярск
    Код (Text):
    1. ; Номер принимаемого от мыши байта
    2. MouseByteNumber_2 DB 0
    3. ; Трехбайтовая структура данных, передаваемая мышью
    4. FirstByte_2       DB 0
    5. SecondByte_2      DB 0
    6. ThirdByte_2       DB 0
    7.  
    8. ;**************************************
    9. ;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ МЫШИ PS/2 *
    10. ;**************************************
    11. check_mouse_data_ps2:
    12.         cmp     [ps2_mouse_detected],0
    13.         je      @@EndMouseInterrupt_2
    14.         call    Wait8042BufferEmpty ;очистка буфера
    15.         in      AL,0x60              ;получить скэн-код
    16. ; Выбирать порядковый номер принимаемого байта
    17.         cmp     [MouseByteNumber_2],0
    18.         je      @@SaveFirstByte
    19.         cmp     [MouseByteNumber_2],1
    20.         je      @@SaveSecondByte
    21.         cmp     [MouseByteNumber_2],2
    22.         je      @@SaveThirdByte
    23.         jmp     @@Error_2
    24. ; Записать первый байт посылки
    25. @@SaveFirstByte:
    26.         test    AL,1000b  ;первый байт посылки?
    27.         jz      @@Error_2     ;сбой синхронизации
    28.         mov     [FirstByte_2],AL
    29.         inc     [MouseByteNumber_2]
    30.         jmp     @@EndMouseInterrupt_2
    31. ; Записать второй байт посылки
    32. @@SaveSecondByte:
    33.         mov     [SecondByte_2],AL
    34.         inc     [MouseByteNumber_2]
    35.         jmp     @@EndMouseInterrupt_2
    36. ; Записать третий байт посылки
    37. @@SaveThirdByte:
    38.         mov     [ThirdByte_2],AL
    39.         mov     [MouseByteNumber_2],0
    40. ; (пакет данных от мыши принят полностью)
    41. ; Записать новое значение байта состояния кнопок
    42.         mov al,[FirstByte_2]   ;[0xfb01]
    43.         and    eax,3
    44.         mov    [0xfb40],al
    45.         mov    [mouse_active],1
    46. ; Вычислить новую X-координату курсора
    47.         ; Занести в AX перемещение по X
    48.         mov     AH,0   ;дублируем знак во все разряды AH
    49.         mov     AL,[FirstByte_2]
    50.         test    AL,10000b    
    51.         jz      @@M0
    52.         mov     AH,0FFh
    53.         ; Занести в AL младший байт
    54. @@M0:
    55.          mov     AL,[SecondByte_2]
    56.          shl  ax,1
    57.         ; Вычислить новое значение координаты
    58.         ; курсора по X
    59.         add     AX,[0xFB0A]    ;[XCoordinate]
    60.         cmp     AX,0
    61.         jge     @@M1
    62.         mov     AX,0
    63.         jmp     @@M2
    64. @@M1:
    65.         cmp     AX,[0xFE00]   ;ScreenLength
    66.         jl      @@M2
    67.         mov     AX,[0xFE00]   ;ScreenLength-1
    68.         dec     ax
    69. @@M2:
    70.         mov     [0xFB0A],AX     ;[XCoordinate]
    71.  
    72. ; Вычисляем новую Y-координату курсора
    73.         ; Занести в AX перемещение по Y
    74.         mov     AH,0   ;дублируем знак во все разряды AH
    75.         mov     AL,[FirstByte_2]
    76.         test    AL,100000b
    77.         jz      @@M3
    78.         mov     AH,0FFh
    79.         ; Занести в AL младший байт
    80. @@M3:
    81.         mov     AL,[ThirdByte_2]
    82.          shl  ax,1
    83.         ; Вычислить новое значение координаты курсора
    84.         ; по Y (Y-координата мыши PS/2 направлена
    85.         ; противоположно экранной)
    86.         neg     AX  
    87.         add     AX,[0xFB0C]   ;[YCoordinate]
    88.         cmp     AX,0
    89.         jge     @@M4
    90.         mov     AX,0
    91.         jmp     @@M5
    92. @@M4:
    93.         cmp     AX,[0xFE04]  ;ScreenHeigth
    94.         jl      @@M5
    95.         mov     AX,[0xFE04] ;ScreenHeigth-1
    96.         dec     ax
    97. @@M5:
    98.         mov     [0xFB0C],AX     ;[YCoordinate]
    99.  
    100. ; Показать курсор в новой позиции
    101.         jmp     @@EndMouseInterrupt_2
    102.  
    103. ; Обнаружен сбой в порядке передачи информации от мыши
    104. @@Error_2:
    105.         mov   [MouseByteNumber_2],0
    106. ; Нормальное завершение прерывания
    107. @@EndMouseInterrupt_2:
    108.         call  ready_for_next_irq_1
    109.         ret
    110.                        
    111. ;***********************************************
    112. ;*   ОЖИДАНИЕ ОЧИСТКИ ВХОДНОГО БУФЕРА I8042    *
    113. ;* При выходе из процедуры:                    *
    114. ;* флаг ZF установлен - нормальное завершение, *
    115. ;* флаг ZF сброшен - ошибка тайм-аута.         *
    116. ;***********************************************
    117. Wait8042BufferEmpty:
    118. ;        push    CX
    119. ;        mov     CX,0FFFFh  ;задать число циклов ожидания
    120. ;@@kb:
    121. ;        in      AL,64h     ;получить статус
    122. ;        test    AL,10b     ;буфер i8042 свободен?
    123. ;        loopnz  @@kb       ;если нет, то цикл
    124. ;        pop     CX
    125.         push ecx
    126.         xor ecx,ecx
    127.       @@:
    128.         in     al,64h
    129.         test    al,00000010b
    130.         loopnz @b
    131.         pop    ecx
    132.         ;Если при выходе из подпрограммы сброшен
    133.         ;флаг ZF - ошибка
    134.         ret                   ;возврат в подпрограмму
    135.  
    136. ;***************************************
    137. ;* ОЖИДАНИЕ ПОСТУПЛЕНИЯ ДАННЫХ ОТ МЫШИ *
    138. ;***************************************
    139. WaitMouseData:
    140. ;        push    CX            
    141. ;        mov     CX,0FFFFh  ;задать число циклов ожидания
    142. ;@@mouse:
    143. ;        in      AL,64h     ;опросить регистр статуса
    144. ;        test    AL,100000b ;данные поступили?
    145. ;        loopz   @@mouse    ;если нет, то цикл
    146. ;        pop     CX
    147.         push ecx
    148.         mov     ECX,0FFFFh
    149.       @@:
    150.         in     al,64h
    151.         test    al,100000b
    152.         loopz @b
    153.         pop    ecx
    154.         ;Если при выходе из подпрограммы установлен
    155.         ;флаг ZF - ошибка
    156.         ret
    это вроде-бы от менуэта. или миракуликса, не помню
     
  8. Toxasoft

    Toxasoft New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2010
    Сообщения:
    188
    Из MenuetOS. Я его пробовал но из за него виснет ось...
    А есть у когонить "примитивный" обработчик?...
     
  9. dinoweb

    dinoweb Дмитрий

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    129
    Адрес:
    Россия. Красноярск
    я делал свой примитивный на основе него, когда разбирался. вроде-бы всё работало. если найду.
    висеть может, если вы, например, не завершаете прерывание перед возвратом. тогда половина аппаратных прерываний остаются запрещёнными.

    Код (Text):
    1.   ...
    2.   mov al, 0x20
    3.   out 0xA0, al
    4.   out 0x20, al
    5.   iret
     
  10. Toxasoft

    Toxasoft New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2010
    Сообщения:
    188
    Сброс заявки в коде правильный это сам обработчик глючит
     
  11. dinoweb

    dinoweb Дмитрий

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    129
    Адрес:
    Россия. Красноярск
    может он у вас с обработчиком клавиатуры конфликтует? пишите подбробнее, что и при каких обстоятельствах у вас зависает. пример рабочий.
     
  12. dinoweb

    dinoweb Дмитрий

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    129
    Адрес:
    Россия. Красноярск
    вот один из моих экспериментов - примитивный обработчик мыши. помню, что работал. глючил с моей usb мышью - разрядности не хватало, и мышь начинала бегать не в ту сторону при резких движениях. с тачпадом таких глюков не было.

    Код (Text):
    1. use64
    2.  
    3. mouse_install:
    4.   mov [rbp+sys.mouse_x], 0
    5.   mov [rbp+sys.mouse_y], 0
    6.   mov [rbp+sys.mouse_pos], 0
    7.   mov [rbp+sys.mouse_x_max], 80
    8.   mov [rbp+sys.mouse_y_max], 25
    9.   mov [rbp+sys.mouse_char], 0
    10.   mov [rbp+sys.mouse_ps2_max], 3
    11.   mov [rbp+sys.mouse_ps2_byte], 0
    12.   mov dword [rbp+sys.mouse_ps2_pack], 0
    13.   mov dword [rbp+sys.mouse_ps2_pack+4], 0
    14.   lea rdx, [ird+extern_mouse_irq]
    15.   mov al, 0x0C
    16.   call apic_io_irq_install
    17.   ret
    18.  
    19.  
    20. extern_mouse_irq:
    21.   push rax rcx rdx rbx rbp rsi rdi r8 r15
    22.   mov ebp, system_base
    23.  
    24.   ; читаем собщение мыши (3 байта). на каждый байт получаем собственное прерывание,
    25.   ; а не как в том примере, ждали в цикле готовности данных
    26.   ; насколько я помню, есть более новый формат сообщения в 4 байта, что здесь не учтено
    27.   in al, 0x60
    28.   mov ecx, [rbp+sys.mouse_ps2_byte]
    29.   mov byte [rbp+sys.mouse_ps2_pack+rcx], al  
    30.   inc ecx
    31.   cmp ecx, [rbp+sys.mouse_ps2_max]
    32.   jnb .pack_complete
    33.   jmp .ok
    34.  
    35.   ; прочитали сообщение полностью, можно обнулить структуру
    36. .done:
    37.   mov dword [rbp+sys.mouse_ps2_pack], 0
    38.   mov dword [rbp+sys.mouse_ps2_pack+4], 0
    39.   mov [rbp+sys.mouse_ps2_max], 3
    40. .ok:
    41.   mov [rbp+sys.mouse_ps2_byte], ecx
    42. .exit:
    43.   mov eax, 0xFEE00000
    44.   mov dword [rax+APIC_LOCAL_EOI], 0
    45.   pop r15 r8 rdi rsi rbp rbx rdx rcx rax
    46.   iretq
    47.  
    48.  
    49. .pack_complete:
    50.   ; Mouse Translate
    51.  
    52.   movzx r8d, byte [rbp+sys.mouse_ps2_pack]
    53.  
    54.   ; вычисляем dX
    55.   mov eax, r8d
    56.   shr eax, 5
    57.   mov dl, [rbp+sys.mouse_ps2_pack+1]
    58.   sbb dh, dh
    59.   movsx rdx, dx
    60.  
    61.   ; вычисляем dY
    62.   mov eax, r8d
    63.   shr eax, 6
    64.   mov cl, [rbp+sys.mouse_ps2_pack+2]
    65.   sbb ch, ch
    66.   movsx rcx, cx
    67.  
    68.   ; А здесь должна быть полезная нагрузка - передать информацию для дальнейшей обработки
    69.   ; ...
    70.    
    71.   xor ecx, ecx
    72.   jmp .done
    upd: убрал лишнее.
     
  13. Toxasoft

    Toxasoft New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2010
    Сообщения:
    188
    dinoweb извини что потратил твое время.
    Я нашол две ошибки:
    -Я далбайоб =)
    -и ставил прерывание не на тот вектор
     
  14. dinoweb

    dinoweb Дмитрий

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    129
    Адрес:
    Россия. Красноярск
    :) бывает
     
  15. shm

    shm New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2010
    Сообщения:
    93
    Да там все точно также как с клавиатурой, мышь несколько раз (для стандартного режима 3) вызывает обработчик прерывания, каждый раз передавая один байт состояния в регистре 0x60. Соответственно принятые данные нужно записывать, а при последнем вызове можно уже обрабатывать или даже курсор рисовать. Только замечу по поводу обработчика, что EOI надо слать еще и ведомую микросхему PIC'а иначе следующее прерывание может не придти.
     
  16. Toxasoft

    Toxasoft New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2010
    Сообщения:
    188
    не может "не придти", а "не придет" т.к irq 0c (мишь) находится на ведомом контролере... я это знаю но все равно спасибо.
     
  17. shm

    shm New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2010
    Сообщения:
    93
    dinoweb, это из примера к справочнику Кулакова вроде.

    В оригинальном примере есть ошибки, все точно не помню, но он не принимает ACK после подачи команды и при чтении данных из порта почему-то проверяет пустоту входного буфера, что конечно неверно. Этот пример в чистом виде у меня не заработал не на одной машине дома.
    Логика передачи однобайтовой команды мыши может быть примерно такой:
    1. Ждем пока освободиться входной буфер (2 бит регистра состояния)
    2. Записываем в порт 0x64 команду 0xD4
    3. Ждем пока освободиться входной буфер (2 бит регистра состояния)
    4. Записываем в порт 0x60 нужную команду
    5. Ждем пока освободиться выходной буфер (1 бит регистра состояния)
    6. Принимаем ACK из порта 0x60 , если за отведенное время ACK не принято то переходим к пункту 4 (так нужно повторять ну раза три хотя-бы, если за это время мышь не ответила, значит что-то не так, скорее всего мышь не подключена :) )
    Если мышь должна передать дополнительные данные, то еще
    7. Ждем пока освободиться выходной буфер (1 бит регистра состояния)
    8. Считываем из порта 0x60 байт данных, если нужно еще считать данные, то переходим к пункту 7
    И, да данный протокол рассчитан естественно, что прерывания от мыши запрещены.
    Вот я так примерно делаю, пока не попалось железа, на котором что-то пошло бы не так.
     
  18. shm

    shm New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2010
    Сообщения:
    93
    Мне как-то попался PIC (блин, не помню уже, что за системная плата была), который даже если в ведомую микросхему EOI не шлешь, то все рано потом прерывания от этого же устройства приходили. Я конечно удивился тогда, и вот сейчас решил высказать более мягко да бы не увидеть ответы типа "а ты гонишь, у меня все работает" :)
     
  19. shm

    shm New Member

    Публикаций:
    0
    Регистрация:
    18 сен 2010
    Сообщения:
    93
    И еще в обработчике прерывания мыши никаких Wait8042BufferEmpty не надо, тем более, что проверяется входной буфер :). Контроллер не подаст сигнал прерывания раньше, чем запишет данный с мыши в выходной буфер.
     
  20. Toxasoft

    Toxasoft New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2010
    Сообщения:
    188
    Видимо создатели MenuetOS(откуда етот обработчик взят) раньше работали в Microsoft. Т.К Microsoft чемпионы по написанию лишнего и бесполезного кода. ))))