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