Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3539 → Rev 5072

/drivers/mouse/commouse.asm/com_mouse.asm
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Includes source code by Kulakov Vladimir Gennadievich. ;;
8,375 → 8,320
;; 02.12.2009 <Lrz> ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;driver sceletone
format PE DLL native
entry START
 
format MS COFF
CURRENT_API = 0x0200
COMPATIBLE_API = 0x0100
API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API
 
DEBUG equ 0
__DEBUG__ = 1
__DEBUG_LEVEL__ = 2
 
include 'proc32.inc'
include 'imports.inc'
section '.flat' readable writable executable
 
API_VERSION equ 5 ;debug
include '../proc32.inc'
include '../struct.inc'
include '../macros.inc'
include '../fdo.inc'
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
; Serial data packet format:
; D6 D5 D4 D3 D2 D1 D0
; 1st byte 1 LB RB Y7 Y6 X7 X6
; 2nd byte 0 X5 X4 X3 X2 X1 X0
; 3rd byte 0 Y5 Y4 Y3 Y2 Y1 Y0
 
virtual at 0
IOCTL IOCTL
end virtual
struct com_mouse_data
 
public START
public version
port dw ?
offset db ?
data rb 3
 
ends
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
STRIDE equ 4 ;size of row in devices table
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; proc START ;;
;; ;;
;; (standard driver proc) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
SRV_GETVERSION equ 0
proc START c, reason:dword, cmdline:dword
 
section '.flat' code readable align 16
cmp [reason], DRV_ENTRY
jne .fail
 
proc START stdcall, state:dword
DEBUGF 2,"Loading serial mouse driver\n"
 
cmp [state], 1
jne .exit
.entry:
;Detect_COM_Mouse:
if DEBUG
mov esi, msgInit
call Boot_Log
end if
mov bx, 0x3f8
call MSMouseSearch
cmp AL, 'M'
jne @f
;mov [com1_mouse_detected],1
;mov [irq_owner+4*4], 1 ; IRQ4 owner is System
stdcall init_mouse, 0x3f8, 4
stdcall init_mouse, 0x2f8, 3
stdcall init_mouse, 0x3e8, 4
stdcall init_mouse, 0x2e8, 3
 
mov dx, bx
inc dx ; 0x3f8 + 1
mov al, 1
out dx, al
invoke RegService, my_service, service_proc
ret
 
stdcall AttachIntHandler, 4, irq4_handler, dword 0
if DEBUG
test eax, eax
jne .label1
 
mov esi, msg_error_attach_int_handler
call Boot_Log
end if
.label1:
; mov eax, 0
; mov ebx, 0x3F8
; mov ecx, 0x3FF
xor ebx, ebx
mov ecx, 0x3F8
mov edx, 0x3FF
call ReservePortArea
 
if DEBUG
cmp eax, 1
jne .go
 
mov esi, msg_error_reserve_ports
call Boot_Log
 
.go:
mov esi, boot_setmouse_type
call Boot_Log
end if
@@:
mov bx, 0x2f8
call MSMouseSearch
cmp AL, 'M'
jne .resume
;mov [com2_mouse_detected],1
;mov [irq_owner+3*4], 1 ; IRQ3 owner is System
 
stdcall AttachIntHandler, 3, irq3_handler, dword 0
 
; mov eax, 0
; mov ebx, 0x2F8
; mov ecx, 0x3F8
xor ebx, ebx
mov ecx, 0x2F8
mov edx, 0x3F8
 
call ReservePortArea
if DEBUG
cmp eax, 1
jne @f
 
mov esi, msg_error_reserve_ports
call Boot_Log
@@:
 
mov esi, boot_setmouse_type + 22
call Boot_Log
end if
.resume:
 
stdcall RegService, my_service, service_proc
if DEBUG
test eax, eax
jne @f
 
mov esi, msg_exit
call Boot_Log
end if
@@:
ret
.fail:
.exit:
if DEBUG
mov esi, msg_exit
call Boot_Log
end if
xor eax, eax
ret
 
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov ebx, [ioctl]
mov eax, [ebx+io_code]
cmp eax, SRV_GETVERSION
jne @F
mov eax, [ebx + IOCTL.io_code]
cmp eax, 0 ;SRV_GETVERSION
jne .fail
 
mov eax, [ebx+output]
cmp [ebx+out_size], 4
mov eax, [ebx + IOCTL.output]
cmp [ebx + IOCTL.out_size], 4
jne .fail
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
 
.fail:
or eax, -1
ret
endp
 
align 4
MSMouseSearch:
; ПОИСК МЫШИ ЧЕРЕЗ COM-ПОРТЫ
MouseSearch:
; Устанавливаем скорость
; приема/передачи 1200 бод
; in bx COM Port Base Address
mov DX, bx
add DX, 3
in AL, DX
or AL, 80h ;установить бит DLAB
out DX, AL
mov DX, bx
mov AL, 60h ;1200 бод
out DX, AL
inc DX
mov AL, 0
out DX, AL
; Установить длину слова 7 бит, 1 стоповый бит,
; четность не контролировать
mov DX, bx
add DX, 3
mov AL, 00000010b
out DX, AL
; Запретить все прерывани
 
proc init_mouse stdcall port, irq
 
DEBUGF 1, "Trying to init serial mouse on port 0x%x\n", [port]
 
xor ebx, ebx ; reserve port area
mov ecx, [port]
lea edx, [ecx + 7]
push ebp
invoke ReservePortArea
pop ebp
test eax, eax
jnz .fail
 
DEBUGF 1, "Reserved port area\n"
 
mov bx, word[port]
 
; Set the speed to 1200 baud
mov dx, bx
add dx, 3
in al, dx
or al, 80h ; set DLAB bit
out dx, al
 
mov dx, bx
mov al, 60h ; 1200 baud
out dx, al
inc dx
mov AL, 0
out DX, AL
; Проверить, что устройство подключено и являетс
; мышью типа MSMouse
; Отключить питание мыши и прерывани
mov DX, bx
add EDX, 4 ;регистр управления модемом
mov AL, 0 ;сбросить DTR, RTS и OUT2
out DX, AL
; Ожидать 5 "тиков" (0,2 с)
mov ecx, 0xFFFF
loop $
; Включить питание мыши
mov al, 0
out dx, al
 
; Use 7 bit words, 1 stop bit, no parity control, reset DLAB bit
mov dx, bx
add dx, 3
mov al, 00000010b
out dx, al
 
; Disable interrupts
mov dx, bx
inc dx
mov al, 0
out dx, al
 
; Check if a MS type serial mouse is connected
 
; Disable power and mouse interrupts
mov dx, bx
add dx, 4 ; modem control register
mov al, 0 ; reset DTR, RTS, and OUT2
out dx, al
 
; Wait 5 ticks (0.2s)
mov esi, 200
invoke Sleep
 
; Power on the mouse
mov al, 1
out dx, al
mov ecx, 0xFFFF
loop $
; Очистить регистр данных
 
; Wait 5 ticks (0.2s)
mov esi, 200
invoke Sleep
 
; Clear data register
mov dx, bx
in AL, DX
add edx, 4
mov AL, 1011b ;установить DTR и RTS и OUT2
out DX, AL
in al, dx
 
; set DTR, DTS and OUT2
add dx, 4
mov al, 1011b
out dx, al
 
mov ecx, 0x1FFFF
; Цикл опроса порта
WaitData:
; Ожидать еще 10 "тиков"
; Poll port
.loop:
dec ecx
; cmp ecx,0
jz NoMouse
; Проверить наличие идентификационного байта
mov DX, bx
add DX, 5
in AL, DX
test AL, 1 ;Данные готовы?
jz WaitData
; Ввести данные
mov DX, bx
in AL, DX
NoMouse:
jz .fail
 
; Check if identification byte is available
mov dx, bx
add dx, 5
in al, dx
test al, 1 ; data ready?
jz .loop
 
; Read data byte
mov dx, bx
in al, dx
cmp al, 'M'
jne .free
 
DEBUGF 2, "Serial mouse detected on port 0x%x\n", [port]
 
; Create data struct
 
invoke Kmalloc, sizeof.com_mouse_data
test eax, eax
jz .fail
 
DEBUGF 1, "Structure 0x%x allocated\n", eax
 
mov bx, word[port]
mov [eax + com_mouse_data.port], bx
mov [eax + com_mouse_data.offset], 0
 
; Attach int handler
 
invoke AttachIntHandler, [irq], irq_handler, eax
test eax, eax
jz .fail
 
DEBUGF 1, "Attached int handler\n"
 
; Enable interrupts
mov dx, word[port]
inc dx
mov al, 1
out dx, al
 
xor eax, eax
ret
 
align 4
irq3_handler:
mov dx, 0x2f8
mov esi, com2_mouse
jmp irq_handler
.free:
DEBUGF 1, "Freeing port area\n"
xor ebx, ebx
inc ebx ; free port area
mov ecx, [port]
lea edx, [ecx + 7]
push ebp
invoke ReservePortArea
pop ebp
 
align 4
irq4_handler:
mov dx, 0x3f8
mov esi, com1_mouse
.fail:
DEBUGF 1, "Failed\n"
or eax, -1
ret
 
endp
 
 
 
irq_handler:
 
; in: esi -> COM_MOUSE_DATA struc, dx = base port (xF8h)
add edx, 5 ; xFDh
push esi
mov esi, [esp+2*4]
 
.read_loop:
mov dx, [esi + com_mouse_data.port]
add dx, 5
in al, dx
test al, 1 ; Данные готовы?
jz .Error
; Ввести данные
sub edx, 5
test al, 1 ; data ready?
jz .end
; read data
sub dx, 5
in al, dx
; Сбросить старший незначащий бит
and al, 01111111b
and al, 01111111b ; clear MSB (use 7 bit words)
 
; Определить порядковый номер принимаемого байта
cmp [esi+COM_MOUSE_DATA.MouseByteNumber], 2
ja .Error
jz .ThirdByte
; Check which data byte we are reading
cmp [esi + com_mouse_data.offset], 2
ja .reset
je .ThirdByte
jp .SecondByte
; Сохранить первый байт данных
.FirstByte:
test al, 1000000b ; Первый байт посылки?
jz .Error
mov [esi+COM_MOUSE_DATA.FirstByte], al
inc [esi+COM_MOUSE_DATA.MouseByteNumber]
jmp .EndMouseInterrupt
; Сохранить второй байт данных
 
; read first data byte
test al, 01000000b ; First byte indicator set?
jz .reset
mov [esi + com_mouse_data.data+0], al
inc [esi + com_mouse_data.offset]
jmp .read_loop
 
; read second data byte
.SecondByte:
test al, 1000000b
jnz .Error
mov [esi+COM_MOUSE_DATA.SecondByte], al
inc [esi+COM_MOUSE_DATA.MouseByteNumber]
jmp .EndMouseInterrupt
; Сохранить третий байт данных
test al, 01000000b ; First byte indicator set?
jnz .reset
mov [esi + com_mouse_data.data+1], al
inc [esi + com_mouse_data.offset]
jmp .read_loop
 
; read third data byte
.ThirdByte:
test al, 1000000b
jnz .Error
mov [esi+COM_MOUSE_DATA.ThirdByte], al
mov [esi+COM_MOUSE_DATA.MouseByteNumber], 0
; (Пакет данных от мыши принят полностью).
; Записать новое значение состояния кнопок мыши
mov al, [esi+COM_MOUSE_DATA.FirstByte]
test al, 01000000b ; First byte indicator set?
jnz .reset
mov [esi + com_mouse_data.data+2], al
 
; Data packet is complete, parse it and set mouse data
 
; Buttons
mov al, [esi + com_mouse_data.data+0]
mov ah, al
shr al, 3
and al, 2
shr ah, 5
and ah, 1
shr al, 3 ; right mouse button
and al, 2 ;
shr ah, 5 ; left mouse button
and ah, 1 ;
add al, ah
movzx eax, al
mov [BTN_DOWN], eax
 
; Прибавить перемещение по X к координате X
mov al, [esi+COM_MOUSE_DATA.FirstByte]
; X coordinate
mov al, [esi + com_mouse_data.data+0]
shl al, 6
or al, [esi+COM_MOUSE_DATA.SecondByte]
 
cbw
movzx eax, ax
or al, [esi + com_mouse_data.data+1]
movsx eax, al
mov [MOUSE_X], eax
 
; Прибавить перемещение по Y к координате Y
mov al, [esi+COM_MOUSE_DATA.FirstByte]
; Y coordinate
mov al, [esi + com_mouse_data.data+0]
and al, 00001100b
shl al, 4
or al, [esi+COM_MOUSE_DATA.ThirdByte]
 
cbw
movzx eax, ax
or al, [esi + com_mouse_data.data+2]
movsx eax, al
neg eax
mov [MOUSE_Y], eax
 
stdcall SetMouseData, [BTN_DOWN], [MOUSE_X], [MOUSE_Y], 0, 0
invoke SetMouseData, [BTN_DOWN], [MOUSE_X], [MOUSE_Y], 0, 0
 
jmp .EndMouseInterrupt
 
.Error:
; Произошел сбой в порядке передачи информации от
; мыши, обнулить счетчик байтов пакета данных
 
mov [esi+COM_MOUSE_DATA.MouseByteNumber], 0
.EndMouseInterrupt:
.reset:
mov [esi + com_mouse_data.offset], 0
.end:
pop esi
mov al, 1
ret
 
;all initialized data place here
 
align 4
; End of code
 
struc COM_MOUSE_DATA {
; Номер принимаемого от мыши байта
.MouseByteNumber db ?
; Трехбайтовая структура данных, передаваемая мышью
.FirstByte db ?
.SecondByte db ?
.ThirdByte db ?
;.timer_ticks_com dd ?
}
virtual at 0
COM_MOUSE_DATA COM_MOUSE_DATA
end virtual
data fixups
end data
 
com1_mouse COM_MOUSE_DATA
com2_mouse COM_MOUSE_DATA
include '../peimport.inc'
 
MOUSE_X dd 0
MOUSE_Y dd 0
BTN_DOWN dd 0
my_service db 'commouse',0 ; max 16 chars include zero
 
COMPortBaseAddr dw 3F8h
include_debug_strings
 
 
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
my_service db 'COM_Mouse',0 ;max 16 chars include zero
 
if DEBUG
msgInit db 'Preved bugoga!',13,10,0
boot_setmouse_type db 'Detected - COM1 mouse',13,10,0
db 'Detected - COM2 mouse',13,10,0
msg_error_reserve_ports db 'Error reserving ports!',13,10,0
msg_error_attach_int_handler db 'Error attach interrupt handler!',13,10,0
msg_exit db 'Exit!',13,10,0
end if
 
section '.data' data readable writable align 16
 
;all uninitialized data place here
 
MOUSE_X dd ?
MOUSE_Y dd ?
BTN_DOWN dd ?