; Запись байта из AH в порт данных микросхемы 8042
write_8042:
in al, 0x64
test al, 10b
jnz write_8042
mov al, ah
out 0x64, al
ret
; Ожидание данных от мыши
wait_mouse_data:
push rcx
mov rcx, 65536
@@:
in al, 0x64
test al, 100000b
loopz @b
pop rcx
ret
; Инициализация драйвера мыши
proc InitMouseDriver stdcall uses rdx,show_messages
local old_text_color
cmp [.show_messages], FALSE
je @f
stdcall GetTextColor,[kernel_console]
mov [.old_text_color], rax
stdcall SetTextColor,[kernel_console],14
stdcall OutString,[kernel_console],addr init_mouse_driver_msg
@@:
invoke SetIntHandler,0x2C,addr MouseHandler
cli
; Запретить генерацию прерывания от мыши
mov ah, 0x20
call write_8042
in al, 0x60
mov dl, al
mov ah, 0x60
call write_8042
mov al, dl
and al, not 10b
out 0x60, al
; Разрешить передачу данных от мыши
mov ah, 0xD4
call write_8042
mov al, 0xF4
out 0x60, al
call wait_mouse_data
jz .error
in al, 0x60
cmp al, 0xFA
jne .error
; Разрешить генерацию прерывания от мыши
mov ah, 0x20
call write_8042
in al, 0x60
mov dl, al
mov ah, 0x60
call write_8042
mov al, dl
or al, 10b
out 0x60, al
sti
cmp [.show_messages], FALSE
je @f
stdcall SetTextColor,[kernel_console],10
stdcall OutString,[kernel_console],addr ok_msg
stdcall SetTextColor,[kernel_console],[.old_text_color]
@@:
mov rax, TRUE
ret
.error:
cmp [.show_messages], FALSE
je @f
stdcall SetTextColor,[kernel_console],4
stdcall OutString,[kernel_console],addr failed_msg
stdcall SetTextColor,[kernel_console],[.old_text_color]
@@:
xor rax, rax
ret
endp
; Обработчик прерывания от мыши
proc MouseHandler interrupt uses rax
stdcall OutChar,[kernel_console],">"
mov al, 0x20
out 0x20, al
out 0xA0, al
ret
endp
Мышь
Код:
Все макросы и системные вызовы ТОЧНО работают нормально. База IRQ - 0x20 для первого контроллера прерываний и 0x28 для второго соотвественно IRQ12 (мышь) имеет номер 0x2C.
Я переписал код из книги Кулакова. Однако прерывание не происходит. Таймаут не происходит и мышь возвращает корректные значения.(функция InitMouseDriver возвращает TRUE).
Может вы сможете подсказать мне где у меня ошибка.
Код:
mov ah, 0xA8
call write_8042
call write_8042
На Bochs все прекрасно работает. А вот при попытке загрузиться на реальной машине происходит таймаут ожидания данных от мыши (wait_mouse_data).
перед установкой параметров девайсы лучше отключать . а включать через некоторое время (1-5мс) после . для пользователя незаметно практически , а вот надёжность повышается .
У Кулакова написанно, что у мыши по умолчанию потоковый режим, но всё равно попробую.
Это не поможет. Я же сказал мышь уже работает на ВМ, а на реальной машине происходит таймаут. На это режим мыши не повлияет.
в эхо-режиме нормально работает ? сколько мышей проверил ?
Я мышь даже включить не могу. Таймаут происходит.
инициализацию начинай с команды reset(0xff)
Что то не вижу смысла в reset!
Это на всякий случай, мало ли что могло случится с мышью до инициализации драйвера. Кстати, после добавления RESET все перестало работать и на виртуальной машине. Мышь возвращает код 0xAA,0x00 и все. Ответы на следующие команды мышь не посылает...
дай исходник .
Код:
; Çàïèñü áàéòà èç AH â ïîðò äàííûõ ìèêðîñõåìû 8042
write_8042:
in al, 0x64
test al, 10b
jnz write_8042
mov al, ah
out 0x64, al
ret
; Îæèäàíèå äàííûõ îò ìûøè
wait_mouse_data:
push rcx
mov rcx, 65536 * 2
@@:
in al, 0x64
test al, 100000b
loopz @b
pop rcx
ret
; Èíèöèàëèçàöèÿ äðàéâåðà ìûøè
proc InitMouseDriver stdcall uses rdx,show_messages
local old_text_color
cmp [.show_messages], FALSE
je @f
stdcall GetTextColor,[kernel_console]
mov [.old_text_color], rax
stdcall SetTextColor,[kernel_console],14
stdcall OutString,[kernel_console],addr init_mouse_driver_msg
@@:
invoke SetIntHandler,0x2C,addr MouseHandler
cli
; Çàïðåòèòü ãåíåðàöèþ ïðåðûâàíèÿ îò ìûøè
mov ah, 0x20
call write_8042
in al, 0x60
mov dl, al
mov ah, 0x60
call write_8042
mov al, dl
and al, not 10b
out 0x60, al
; Ðàçðåøèòü èíòåðôåéñ ìûøè
mov ah, 0xA8
call write_8042
; Îáíóëèì äàííûå ïàêåòà îò ìûøè
mov [mouse_packet.max_count], 3
mov [mouse_packet.count], 0
mov dword[mouse_packet.data], 0
; Íàñòðîèì óêàçàòåëü ìûøè
mov [mouse_pointer_x], 80 / 2
mov [mouse_pointer_y], 25 / 2
mov [mouse_pointer_max_x], 80
mov [mouse_pointer_max_y], 25
; Îáíóëèì ñîñòîÿíèÿ êíîïîê
mov [mouse_lbutton], FALSE
mov [mouse_rbutton], FALSE
mov [mouse_mbutton], FALSE
; Ðàçðåøèòü ïåðåäà÷ó äàííûõ îò ìûøè
mov ah, 0xD4
call write_8042
mov al, 0xF4
out 0x60, al
call wait_mouse_data
jz .error
in al, 0x60
cmp al, 0xFA
jne .error
; Ðàçðåøèòü ãåíåðàöèþ ïðåðûâàíèÿ îò ìûøè
mov ah, 0x20
call write_8042
in al, 0x60
mov dl, al
mov ah, 0x60
call write_8042
mov al, dl
or al, 10b
out 0x60, al
sti
cmp [.show_messages], FALSE
je @f
stdcall SetTextColor,[kernel_console],10
stdcall OutString,[kernel_console],addr ok_msg
stdcall SetTextColor,[kernel_console],[.old_text_color]
@@:
mov rax, TRUE
ret
.error:
sti
cmp [.show_messages], FALSE
je @f
stdcall SetTextColor,[kernel_console],4
stdcall OutString,[kernel_console],addr failed_msg
stdcall SetTextColor,[kernel_console],[.old_text_color]
@@:
xor rax, rax
ret
endp
; Îáðàáîò÷èê ïðåðûâàíèÿ îò ìûøè
proc MouseHandler interrupt uses rax rdx
@@:
in al, 0x64
test al, 10b
jnz @b
in al, 0x60
cmp [mouse_packet.count], 0
ja @f
test al, 1000b
jz .new_packet
@@:
mov rdx, mouse_packet.data
add rdx, [mouse_packet.count]
mov [rdx], al
inc [mouse_packet.count]
mov rax, [mouse_packet.max_count]
cmp [mouse_packet.count], rax
jb .exit
xor ah, ah
test [mouse_packet.data], 10000b
jz @f
mov ah, 0xFF
@@:
mov al, [mouse_packet.data + 1]
movsx rax, ax
add [mouse_pointer_x], rax
cmp [mouse_pointer_x], 0xFFFF
jb @f
mov [mouse_pointer_x], 0
@@:
mov rax, [mouse_pointer_max_x]
cmp [mouse_pointer_x], rax
jb @f
dec rax
mov [mouse_pointer_x], rax
@@:
xor ah, ah
test [mouse_packet.data], 100000b
jz @f
mov ah, 0xFF
@@:
mov al, [mouse_packet.data + 2]
movsx rax, ax
neg rax
add [mouse_pointer_y], rax
cmp [mouse_pointer_y], 0xFFFF
jb @f
mov [mouse_pointer_y], 0
@@:
mov rax, [mouse_pointer_max_y]
cmp [mouse_pointer_y], rax
jb @f
dec rax
mov [mouse_pointer_y], rax
@@:
bt dword[mouse_packet.data], 2
setc byte[mouse_mbutton]
bt dword[mouse_packet.data], 1
setc byte[mouse_lbutton]
bt dword[mouse_packet.data], 0
setc byte[mouse_rbutton]
cmp [mouse_handler], NULL
je @f
stdcall [mouse_handler]
test rax, rax
jnz .new_packet
@@:
stdcall UpdateScreen
.new_packet:
mov [mouse_packet.count], 0
.exit:
mov al, 0x20
out 0x20, al
out 0xA0, al
ret
endp
write_8042:
in al, 0x64
test al, 10b
jnz write_8042
mov al, ah
out 0x64, al
ret
; Îæèäàíèå äàííûõ îò ìûøè
wait_mouse_data:
push rcx
mov rcx, 65536 * 2
@@:
in al, 0x64
test al, 100000b
loopz @b
pop rcx
ret
; Èíèöèàëèçàöèÿ äðàéâåðà ìûøè
proc InitMouseDriver stdcall uses rdx,show_messages
local old_text_color
cmp [.show_messages], FALSE
je @f
stdcall GetTextColor,[kernel_console]
mov [.old_text_color], rax
stdcall SetTextColor,[kernel_console],14
stdcall OutString,[kernel_console],addr init_mouse_driver_msg
@@:
invoke SetIntHandler,0x2C,addr MouseHandler
cli
; Çàïðåòèòü ãåíåðàöèþ ïðåðûâàíèÿ îò ìûøè
mov ah, 0x20
call write_8042
in al, 0x60
mov dl, al
mov ah, 0x60
call write_8042
mov al, dl
and al, not 10b
out 0x60, al
; Ðàçðåøèòü èíòåðôåéñ ìûøè
mov ah, 0xA8
call write_8042
; Îáíóëèì äàííûå ïàêåòà îò ìûøè
mov [mouse_packet.max_count], 3
mov [mouse_packet.count], 0
mov dword[mouse_packet.data], 0
; Íàñòðîèì óêàçàòåëü ìûøè
mov [mouse_pointer_x], 80 / 2
mov [mouse_pointer_y], 25 / 2
mov [mouse_pointer_max_x], 80
mov [mouse_pointer_max_y], 25
; Îáíóëèì ñîñòîÿíèÿ êíîïîê
mov [mouse_lbutton], FALSE
mov [mouse_rbutton], FALSE
mov [mouse_mbutton], FALSE
; Ðàçðåøèòü ïåðåäà÷ó äàííûõ îò ìûøè
mov ah, 0xD4
call write_8042
mov al, 0xF4
out 0x60, al
call wait_mouse_data
jz .error
in al, 0x60
cmp al, 0xFA
jne .error
; Ðàçðåøèòü ãåíåðàöèþ ïðåðûâàíèÿ îò ìûøè
mov ah, 0x20
call write_8042
in al, 0x60
mov dl, al
mov ah, 0x60
call write_8042
mov al, dl
or al, 10b
out 0x60, al
sti
cmp [.show_messages], FALSE
je @f
stdcall SetTextColor,[kernel_console],10
stdcall OutString,[kernel_console],addr ok_msg
stdcall SetTextColor,[kernel_console],[.old_text_color]
@@:
mov rax, TRUE
ret
.error:
sti
cmp [.show_messages], FALSE
je @f
stdcall SetTextColor,[kernel_console],4
stdcall OutString,[kernel_console],addr failed_msg
stdcall SetTextColor,[kernel_console],[.old_text_color]
@@:
xor rax, rax
ret
endp
; Îáðàáîò÷èê ïðåðûâàíèÿ îò ìûøè
proc MouseHandler interrupt uses rax rdx
@@:
in al, 0x64
test al, 10b
jnz @b
in al, 0x60
cmp [mouse_packet.count], 0
ja @f
test al, 1000b
jz .new_packet
@@:
mov rdx, mouse_packet.data
add rdx, [mouse_packet.count]
mov [rdx], al
inc [mouse_packet.count]
mov rax, [mouse_packet.max_count]
cmp [mouse_packet.count], rax
jb .exit
xor ah, ah
test [mouse_packet.data], 10000b
jz @f
mov ah, 0xFF
@@:
mov al, [mouse_packet.data + 1]
movsx rax, ax
add [mouse_pointer_x], rax
cmp [mouse_pointer_x], 0xFFFF
jb @f
mov [mouse_pointer_x], 0
@@:
mov rax, [mouse_pointer_max_x]
cmp [mouse_pointer_x], rax
jb @f
dec rax
mov [mouse_pointer_x], rax
@@:
xor ah, ah
test [mouse_packet.data], 100000b
jz @f
mov ah, 0xFF
@@:
mov al, [mouse_packet.data + 2]
movsx rax, ax
neg rax
add [mouse_pointer_y], rax
cmp [mouse_pointer_y], 0xFFFF
jb @f
mov [mouse_pointer_y], 0
@@:
mov rax, [mouse_pointer_max_y]
cmp [mouse_pointer_y], rax
jb @f
dec rax
mov [mouse_pointer_y], rax
@@:
bt dword[mouse_packet.data], 2
setc byte[mouse_mbutton]
bt dword[mouse_packet.data], 1
setc byte[mouse_lbutton]
bt dword[mouse_packet.data], 0
setc byte[mouse_rbutton]
cmp [mouse_handler], NULL
je @f
stdcall [mouse_handler]
test rax, rax
jnz .new_packet
@@:
stdcall UpdateScreen
.new_packet:
mov [mouse_packet.count], 0
.exit:
mov al, 0x20
out 0x20, al
out 0xA0, al
ret
endp
Это код без сброса мыши. Отлично работает на виртуальной машине (Bochs), но на реальном компьютере ничего не работает - происходит таймаут.
затем команда "set wrap mode" (0х0edh) - эхо режим для тестирования ;
передаём/принимаем тестовую последовательность (например 0x0ffh,0x0aah,0x55h,0x00) .
если всё в порядке отключаем эхо режим (0x0ech) , устанавливаем параметры и ставим обработчик прерывания .
и в последнюю очередь разрешаем работу мыши (0х0f4h) .
Код:
; Çàïðåòèòü ãåíåðàöèþ ïðåðûâàíèÿ îò ìûøè
mov ah, 0x20
call write_8042
in al, 0x60
mov dl, al
mov ah, 0x60
call write_8042
mov al, dl
and al, not 10b
out 0x60, al
; Ðàçðåøèòü èíòåðôåéñ ìûøè
mov ah, 0xA8
call write_8042
; Ñáðîñèì ìûøü
mov ah, 0xD4
call write_8042
mov al, 0xFF
out 0x60, al
call wait_mouse_data
in al, 0x60
cmp al, 0xFA
jne .error
invoke GetTimer
lea rdx, [rax + 50] ; Òàéìåð ñðàáàòûâàåò 100 ðàç â ñåêóíäó
@@:
in al, 0x64
test al, 100000b
jnz @f
invoke GetTimer
cmp rax, rdx
jb @b
jmp .error
@@:
in al, 0x60
cmp al, 0xAA
jne .error
call wait_mouse_data
in al, 0x60
test al, al ; cmp al, 0x00
jne .error
mov ah, 0x20
call write_8042
in al, 0x60
mov dl, al
mov ah, 0x60
call write_8042
mov al, dl
and al, not 10b
out 0x60, al
; Ðàçðåøèòü èíòåðôåéñ ìûøè
mov ah, 0xA8
call write_8042
; Ñáðîñèì ìûøü
mov ah, 0xD4
call write_8042
mov al, 0xFF
out 0x60, al
call wait_mouse_data
in al, 0x60
cmp al, 0xFA
jne .error
invoke GetTimer
lea rdx, [rax + 50] ; Òàéìåð ñðàáàòûâàåò 100 ðàç â ñåêóíäó
@@:
in al, 0x64
test al, 100000b
jnz @f
invoke GetTimer
cmp rax, rdx
jb @b
jmp .error
@@:
in al, 0x60
cmp al, 0xAA
jne .error
call wait_mouse_data
in al, 0x60
test al, al ; cmp al, 0x00
jne .error
В эхо режим правда пока не переводил, но на Bochs теперь работает. Значит я до этого что то не так делал (жалко код не сохранился чтобы сравнить). На реальной машине позже попробую...
http://forum.codenet.ru/showthread.php?t=59193).
Мышь опять не работает(( Я использовал код с RESET'ом. В чем еще может быть дело?
Теперь у меня появилась возможность загрузиться на реальной манине (
Мышь опять не работает(( Я использовал код с RESET'ом. В чем еще может быть дело?
mov ah, 0xD4
call write_8042
mov al, 0xF4
out 0x60, al
call wait_mouse_data
in al, 0x60
cmp al, 0xFA
jne .error