Rev 5076 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2288 | clevermous | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
5363 | yogev_ezra | 3 | ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; |
2288 | clevermous | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;; Includes source code by Kulakov Vladimir Gennadievich. ;; |
||
7 | ;; Modified by Mario79 and Rus. ;; |
||
8 | ;; 02.12.2009 |
||
9 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
10 | |||
5072 | hidnplayr | 11 | format PE DLL native |
12 | entry START |
||
2288 | clevermous | 13 | |
5072 | hidnplayr | 14 | CURRENT_API = 0x0200 |
15 | COMPATIBLE_API = 0x0100 |
||
16 | API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API |
||
2288 | clevermous | 17 | |
5072 | hidnplayr | 18 | __DEBUG__ = 1 |
19 | __DEBUG_LEVEL__ = 2 |
||
2288 | clevermous | 20 | |
5072 | hidnplayr | 21 | section '.flat' readable writable executable |
2288 | clevermous | 22 | |
5072 | hidnplayr | 23 | include '../proc32.inc' |
24 | include '../struct.inc' |
||
25 | include '../macros.inc' |
||
26 | include '../fdo.inc' |
||
2288 | clevermous | 27 | |
5072 | hidnplayr | 28 | ; Serial data packet format: |
29 | ; D6 D5 D4 D3 D2 D1 D0 |
||
30 | ; 1st byte 1 LB RB Y7 Y6 X7 X6 |
||
31 | ; 2nd byte 0 X5 X4 X3 X2 X1 X0 |
||
32 | ; 3rd byte 0 Y5 Y4 Y3 Y2 Y1 Y0 |
||
2288 | clevermous | 33 | |
5075 | hidnplayr | 34 | ; optional: (logitech extension protocol) |
35 | ; 4th byte 0 MB 0 0 0 0 0 |
||
36 | |||
5072 | hidnplayr | 37 | struct com_mouse_data |
2288 | clevermous | 38 | |
5072 | hidnplayr | 39 | port dw ? |
40 | offset db ? |
||
41 | data rb 3 |
||
2288 | clevermous | 42 | |
5072 | hidnplayr | 43 | ends |
2288 | clevermous | 44 | |
5072 | hidnplayr | 45 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
46 | ;; ;; |
||
47 | ;; proc START ;; |
||
48 | ;; ;; |
||
49 | ;; (standard driver proc) ;; |
||
50 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
2288 | clevermous | 51 | |
5072 | hidnplayr | 52 | proc START c, reason:dword, cmdline:dword |
2288 | clevermous | 53 | |
5072 | hidnplayr | 54 | cmp [reason], DRV_ENTRY |
55 | jne .fail |
||
2288 | clevermous | 56 | |
5072 | hidnplayr | 57 | DEBUGF 2,"Loading serial mouse driver\n" |
2288 | clevermous | 58 | |
5072 | hidnplayr | 59 | stdcall init_mouse, 0x3f8, 4 |
60 | stdcall init_mouse, 0x2f8, 3 |
||
61 | stdcall init_mouse, 0x3e8, 4 |
||
62 | stdcall init_mouse, 0x2e8, 3 |
||
2288 | clevermous | 63 | |
5072 | hidnplayr | 64 | invoke RegService, my_service, service_proc |
65 | ret |
||
2288 | clevermous | 66 | |
5072 | hidnplayr | 67 | .fail: |
2288 | clevermous | 68 | xor eax, eax |
69 | ret |
||
5072 | hidnplayr | 70 | |
2288 | clevermous | 71 | endp |
72 | |||
73 | |||
74 | proc service_proc stdcall, ioctl:dword |
||
75 | |||
76 | mov ebx, [ioctl] |
||
5072 | hidnplayr | 77 | mov eax, [ebx + IOCTL.io_code] |
78 | cmp eax, 0 ;SRV_GETVERSION |
||
79 | jne .fail |
||
2288 | clevermous | 80 | |
5072 | hidnplayr | 81 | mov eax, [ebx + IOCTL.output] |
82 | cmp [ebx + IOCTL.out_size], 4 |
||
2288 | clevermous | 83 | jne .fail |
84 | mov [eax], dword API_VERSION |
||
85 | xor eax, eax |
||
86 | ret |
||
5072 | hidnplayr | 87 | |
88 | .fail: |
||
2288 | clevermous | 89 | or eax, -1 |
90 | ret |
||
91 | endp |
||
92 | |||
5072 | hidnplayr | 93 | |
94 | proc init_mouse stdcall port, irq |
||
95 | |||
96 | DEBUGF 1, "Trying to init serial mouse on port 0x%x\n", [port] |
||
97 | |||
98 | xor ebx, ebx ; reserve port area |
||
99 | mov ecx, [port] |
||
100 | lea edx, [ecx + 7] |
||
101 | push ebp |
||
102 | invoke ReservePortArea |
||
103 | pop ebp |
||
104 | test eax, eax |
||
105 | jnz .fail |
||
106 | |||
107 | DEBUGF 1, "Reserved port area\n" |
||
108 | |||
109 | mov bx, word[port] |
||
110 | |||
111 | ; Set the speed to 1200 baud |
||
2288 | clevermous | 112 | mov dx, bx |
5072 | hidnplayr | 113 | add dx, 3 |
114 | in al, dx |
||
115 | or al, 80h ; set DLAB bit |
||
116 | out dx, al |
||
117 | |||
118 | mov dx, bx |
||
119 | mov al, 60h ; 1200 baud |
||
120 | out dx, al |
||
2288 | clevermous | 121 | inc dx |
5072 | hidnplayr | 122 | mov al, 0 |
123 | out dx, al |
||
124 | |||
125 | ; Use 7 bit words, 1 stop bit, no parity control, reset DLAB bit |
||
126 | mov dx, bx |
||
127 | add dx, 3 |
||
128 | mov al, 00000010b |
||
129 | out dx, al |
||
130 | |||
131 | ; Disable interrupts |
||
132 | mov dx, bx |
||
133 | inc dx |
||
134 | mov al, 0 |
||
135 | out dx, al |
||
136 | |||
137 | ; Check if a MS type serial mouse is connected |
||
138 | |||
139 | ; Disable power and mouse interrupts |
||
140 | mov dx, bx |
||
141 | add dx, 4 ; modem control register |
||
5076 | hidnplayr | 142 | mov al, 0 ; reset DTR, RTS, and AUX2 |
5072 | hidnplayr | 143 | out dx, al |
144 | |||
145 | ; Wait 5 ticks (0.2s) |
||
146 | mov esi, 200 |
||
147 | invoke Sleep |
||
148 | |||
149 | ; Power on the mouse |
||
2288 | clevermous | 150 | mov al, 1 |
151 | out dx, al |
||
5072 | hidnplayr | 152 | |
153 | ; Wait 5 ticks (0.2s) |
||
154 | mov esi, 200 |
||
155 | invoke Sleep |
||
156 | |||
157 | ; Clear data register |
||
2288 | clevermous | 158 | mov dx, bx |
5072 | hidnplayr | 159 | in al, dx |
160 | |||
5076 | hidnplayr | 161 | ; Power on the mouse |
5072 | hidnplayr | 162 | add dx, 4 |
5076 | hidnplayr | 163 | mov al, 1011b ; set DTR, DTS and AUX2 |
5072 | hidnplayr | 164 | out dx, al |
165 | |||
2288 | clevermous | 166 | mov ecx, 0x1FFFF |
5072 | hidnplayr | 167 | ; Poll port |
168 | .loop: |
||
2288 | clevermous | 169 | dec ecx |
5072 | hidnplayr | 170 | jz .fail |
171 | |||
172 | ; Check if identification byte is available |
||
173 | mov dx, bx |
||
174 | add dx, 5 |
||
175 | in al, dx |
||
176 | test al, 1 ; data ready? |
||
177 | jz .loop |
||
178 | |||
179 | ; Read data byte |
||
180 | mov dx, bx |
||
181 | in al, dx |
||
182 | cmp al, 'M' |
||
183 | jne .free |
||
184 | |||
185 | DEBUGF 2, "Serial mouse detected on port 0x%x\n", [port] |
||
186 | |||
187 | ; Create data struct |
||
188 | |||
189 | invoke Kmalloc, sizeof.com_mouse_data |
||
190 | test eax, eax |
||
191 | jz .fail |
||
192 | |||
193 | DEBUGF 1, "Structure 0x%x allocated\n", eax |
||
194 | |||
195 | mov bx, word[port] |
||
196 | mov [eax + com_mouse_data.port], bx |
||
197 | mov [eax + com_mouse_data.offset], 0 |
||
198 | |||
199 | ; Attach int handler |
||
200 | |||
201 | invoke AttachIntHandler, [irq], irq_handler, eax |
||
202 | test eax, eax |
||
203 | jz .fail |
||
204 | |||
205 | DEBUGF 1, "Attached int handler\n" |
||
206 | |||
207 | ; Enable interrupts |
||
208 | mov dx, word[port] |
||
209 | inc dx |
||
210 | mov al, 1 |
||
211 | out dx, al |
||
212 | |||
213 | xor eax, eax |
||
2288 | clevermous | 214 | ret |
215 | |||
5072 | hidnplayr | 216 | .free: |
217 | DEBUGF 1, "Freeing port area\n" |
||
218 | xor ebx, ebx |
||
219 | inc ebx ; free port area |
||
220 | mov ecx, [port] |
||
221 | lea edx, [ecx + 7] |
||
222 | push ebp |
||
223 | invoke ReservePortArea |
||
224 | pop ebp |
||
2288 | clevermous | 225 | |
5072 | hidnplayr | 226 | .fail: |
227 | DEBUGF 1, "Failed\n" |
||
228 | or eax, -1 |
||
229 | ret |
||
2288 | clevermous | 230 | |
5072 | hidnplayr | 231 | endp |
232 | |||
233 | |||
234 | |||
2288 | clevermous | 235 | irq_handler: |
236 | |||
5072 | hidnplayr | 237 | push esi |
238 | mov esi, [esp+2*4] |
||
239 | |||
240 | .read_loop: |
||
241 | mov dx, [esi + com_mouse_data.port] |
||
242 | add dx, 5 |
||
2288 | clevermous | 243 | in al, dx |
5072 | hidnplayr | 244 | test al, 1 ; data ready? |
245 | jz .end |
||
246 | ; read data |
||
247 | sub dx, 5 |
||
2288 | clevermous | 248 | in al, dx |
5072 | hidnplayr | 249 | and al, 01111111b ; clear MSB (use 7 bit words) |
5075 | hidnplayr | 250 | test al, 01000000b ; First byte indicator set? |
251 | jnz .FirstByte |
||
2288 | clevermous | 252 | |
5072 | hidnplayr | 253 | ; Check which data byte we are reading |
5075 | hidnplayr | 254 | cmp [esi + com_mouse_data.offset], 1 |
255 | jb .SecondByte |
||
5072 | hidnplayr | 256 | je .ThirdByte |
5075 | hidnplayr | 257 | ja .FourthByte |
5072 | hidnplayr | 258 | |
259 | ; read first data byte |
||
5075 | hidnplayr | 260 | .FirstByte: |
5072 | hidnplayr | 261 | mov [esi + com_mouse_data.data+0], al |
5075 | hidnplayr | 262 | mov [esi + com_mouse_data.offset], 0 |
5072 | hidnplayr | 263 | jmp .read_loop |
264 | |||
265 | ; read second data byte |
||
266 | .SecondByte: |
||
267 | mov [esi + com_mouse_data.data+1], al |
||
268 | inc [esi + com_mouse_data.offset] |
||
269 | jmp .read_loop |
||
270 | |||
271 | ; read third data byte |
||
272 | .ThirdByte: |
||
273 | mov [esi + com_mouse_data.data+2], al |
||
5075 | hidnplayr | 274 | inc [esi + com_mouse_data.offset] |
5072 | hidnplayr | 275 | |
276 | ; Data packet is complete, parse it and set mouse data |
||
277 | |||
5075 | hidnplayr | 278 | ; Left and Right Buttons |
5072 | hidnplayr | 279 | mov al, [esi + com_mouse_data.data+0] |
2288 | clevermous | 280 | mov ah, al |
5072 | hidnplayr | 281 | shr al, 3 ; right mouse button |
5076 | hidnplayr | 282 | and al, 10b ; |
5072 | hidnplayr | 283 | shr ah, 5 ; left mouse button |
5076 | hidnplayr | 284 | and ah, 1b ; |
285 | or al, ah |
||
286 | and [BTN_DOWN], not 11b |
||
287 | or byte[BTN_DOWN], al |
||
2288 | clevermous | 288 | |
5075 | hidnplayr | 289 | ; X coordinate |
5072 | hidnplayr | 290 | mov al, [esi + com_mouse_data.data+0] |
2288 | clevermous | 291 | shl al, 6 |
5072 | hidnplayr | 292 | or al, [esi + com_mouse_data.data+1] |
293 | movsx eax, al |
||
2288 | clevermous | 294 | mov [MOUSE_X], eax |
295 | |||
5075 | hidnplayr | 296 | ; Y coordinate |
5072 | hidnplayr | 297 | mov al, [esi + com_mouse_data.data+0] |
2288 | clevermous | 298 | and al, 00001100b |
299 | shl al, 4 |
||
5072 | hidnplayr | 300 | or al, [esi + com_mouse_data.data+2] |
301 | movsx eax, al |
||
2288 | clevermous | 302 | neg eax |
303 | mov [MOUSE_Y], eax |
||
304 | |||
5072 | hidnplayr | 305 | invoke SetMouseData, [BTN_DOWN], [MOUSE_X], [MOUSE_Y], 0, 0 |
2288 | clevermous | 306 | |
5075 | hidnplayr | 307 | pop esi |
308 | mov al, 1 |
||
309 | ret |
||
310 | |||
311 | .FourthByte: |
||
5076 | hidnplayr | 312 | cmp [esi + com_mouse_data.offset], 2 |
313 | jne .end |
||
5075 | hidnplayr | 314 | inc [esi + com_mouse_data.offset] |
315 | |||
5076 | hidnplayr | 316 | and [BTN_DOWN], not 100b |
5075 | hidnplayr | 317 | test al, 00100000b |
5076 | hidnplayr | 318 | jz @f |
319 | or byte[BTN_DOWN], 100b |
||
320 | @@: |
||
321 | invoke SetMouseData, [BTN_DOWN], 0, 0, 0, 0 |
||
5075 | hidnplayr | 322 | |
5072 | hidnplayr | 323 | .end: |
324 | pop esi |
||
2288 | clevermous | 325 | mov al, 1 |
326 | ret |
||
327 | |||
328 | |||
5075 | hidnplayr | 329 | |
330 | |||
5072 | hidnplayr | 331 | ; End of code |
2288 | clevermous | 332 | |
5072 | hidnplayr | 333 | data fixups |
334 | end data |
||
2288 | clevermous | 335 | |
5072 | hidnplayr | 336 | include '../peimport.inc' |
2288 | clevermous | 337 | |
5072 | hidnplayr | 338 | my_service db 'commouse',0 ; max 16 chars include zero |
2288 | clevermous | 339 | |
5072 | hidnplayr | 340 | include_debug_strings |
2288 | clevermous | 341 | |
5072 | hidnplayr | 342 | MOUSE_X dd ? |
343 | MOUSE_Y dd ? |
||
344 | BTN_DOWN dd ? |