Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1818 Albom 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;
3
;   PSX-Pad for KolibriOS
4
;   Copyright (C) Jeffrey Amelynck 2008. All rights reserved.
5
;
6
;   hidnplayr@kolibrios.org
7
;
8
;   v0.1
9
;   date: 4/09/2008
10
;   type: private beta
11
;   functions implemented: Read raw data from Digital controller and Analog controller with red led.
12
;
13
;   v0.2:
14
;   date: 5/09/2008
15
;   type: public beta
16
;   functions implemented: Same as above plus converting keycodes from keypad do keyboard scancodes.
17
;                        : To use this function you need a kernel wich can input scancodes using function 18,23.
18
;                        ; I also did some cleanup and speedup
19
;
20
;
21
;   v0.2.1
22
;   by O. Bogomaz aka Albom, albom85@yandex.ru
23
;   using of standart kernel function 72.1
24
;
25
;
26
;   TODO: - Multiple controllers
27
;         - Analog controller(s)
28
;
29
;
30
;   More info about PSX/PS2 gamepad protocol:
31
;   http://curiousinventor.com/guides/ps2
32
;   http://www.geocities.com/digitan000/Hardware/22/e22_page.html
33
;
34
;   How to connect your PSX pad to the PC:
35
;   http://www.emulatronia.com/reportajes/directpad/psxeng/print.htm
36
;
37
;
38
;   PSX-Pad for KolibriOS is distributed in the hope that it will be useful,
39
;   but WITHOUT ANY WARRANTY.
40
;   No author or distributor accepts responsibility to anyone for the
41
;   consequences of using it or for whether it serves any particular purpose or
42
;   works at all, unless he says so in writing. Refer to the GNU General Public
43
;   License (the "GPL") for full details.
44
;
45
;   Everyone is granted permission to copy, modify and redistribute KolibriOS,
46
;   but only under the conditions described in the GPL. A copy of this license
47
;   is supposed to have been given to you along with KolibriOS so you can know
48
;   your rights and responsibilities. It should be in a file named COPYING.
49
;   Among other things, the copyright notice and this notice must be preserved
50
;   on all copies.
51
;
52
 
53
use32
54
 
55
		org    0x0
56
 
57
		db     'MENUET01'	       ; 8 byte id
58
		dd     0x01		           ; header version
59
		dd     START		       ; start of code
60
		dd     I_END		       ; size of image
61
		dd     0x100000 	       ; memory for app
62
		dd     0x100000 	       ; esp
63
		dd     0x0 , 0x0	       ; I_Param , I_Icon
64
 
65
; Bits on Data Port (outputs for pc)
66
command 	equ 0
67
attention	equ 1
68
clock		equ 2
69
vcc		equ (1 shl 3 + 1 shl 4 + 1 shl 5 + 1 shl 6 + 1 shl 7)
70
 
71
; Bits on Status Port (inputs for PC)
72
data		equ 6
73
ack		equ 5
74
 
75
__DEBUG__ equ 1
76
__DEBUG_LEVEL__ equ 2
77
 
78
include '../../macros.inc'
79
;include 'fdo.inc'
80
 
81
START:
82
  mov	eax, 40       ; Disable notification of all events
83
  xor	ebx, ebx
84
  int	0x40
85
 
86
;  DEBUGF 2,"\nPSX-Pad for KolibriOS v0.2\n\n"
87
 
88
  mov	eax, 46       ; Ask the kernel if wse may use the LPT port
89
  mov	ebx, 0
90
  movzx ecx, [BASE]
91
  movzx edx, [CONTROL]
92
  int	0x40
93
  test	eax, eax
94
  jz	@f
95
 
96
;  DEBUGF 2,"Could not reserve port!\n"
97
  jmp	exit
98
@@:
99
 
100
  mov	dx, [CONTROL] ; disable bi-directional data port
101
  in	al, dx
102
  and	al, 0xdf
103
  out	dx, al
104
 
105
  mov	eax, 18       ; read CPU-speed, we'll need it for 100us delay
106
  mov	ebx, 5
107
  int	0x40	      ; now we've got the cpuspeed in hz, we need it in Mhz
108
  xor	edx, edx
109
  mov	ecx, 1000000
110
  div	ecx
111
  mov	[CPUSPEED], eax
112
;  DEBUGF 2,"CPUspeed: %u\n",eax
113
 
114
;  DEBUGF 1,"Raising attention line\n"
115
  call	raise_att
116
 
117
;  DEBUGF 1,"Raising Clock\n"
118
  call	raise_clk
119
 
120
;  DEBUGF 1,"Powering Up controller\n"
121
  call	raise_vcc
122
 
123
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
124
;
125
; All things are ready to go, enter mainloop!
126
;
127
; This loop constantly poll's the PSX-pad for data
128
;
129
 
130
mainloop:
131
 
132
  mov	eax, 5	    ; Lets start by giving the other applications some cpu time, we'll take ours later.
133
  mov	ebx, 5
134
  int	0x40
135
 
136
;  DEBUGF 1,"Lowering attention line\n"
137
  call	lower_att   ; We've got the attention from the PSX-Pad now :) (yes, it's active low..)
138
 
139
;  DEBUGF 1,"Sending Startup byte.. "
140
  mov	ah, 0x01    ; Startup code
141
  call	tx_rx
142
  call	wait_for_ack
143
;  DEBUGF 1,"Rx: %x\n",bl
144
 
145
;  DEBUGF 1,"Request for data.. "
146
  mov	ah, 0x42    ; Request for data
147
  call	tx_rx
148
  call	wait_for_ack
149
;  DEBUGF 1,"Rx: %x\n",bl
150
 
151
  cmp	bl, 0x41
152
  je	digital_controller
153
 
154
  cmp	bl, 0x73
155
  je	analog_red_controller
156
 
157
;  cmp   ah, 0x23
158
;  je    negcon_controller
159
 
160
;  cmp   ah, 0x53
161
;  je    analog_green_controller
162
 
163
;  cmp   ah, 0x12
164
;  je    psx_mouse
165
 
166
 
167
;  DEBUGF 2,"Unsupported controller/mode:%x !\n",bl
168
  jmp	exit
169
 
170
 
171
 
172
 
173
digital_controller:
174
  call	command_idle
175
  call	wait_for_ack
176
  ; Right now, we receive 0x5a from the controller, wich means: sending data!
177
;  DEBUGF 1,"Receiving data.. "
178
 
179
  call	command_idle
180
  call	wait_for_ack
181
  mov	byte [digital+1], bl
182
 
183
  call	command_idle
184
  mov	byte [digital+0], bl
185
 
186
;  DEBUGF 1,"Digital data: %x\n",[digital]:4
187
 
188
  mov	ax, word [digital_]
189
  xor	ax, word [digital]
190
  mov	cx, word [digital]
191
 
192
  bt	ax, 6	  ; X
193
  jnc	@f
194
  pusha
195
  and	cx, 1 shl 6
196
  shl	cx, 1
197
  add	cl, 29
198
  call	sendkey
199
  popa
200
@@:
201
 
202
  bt	ax, 5	  ; O
203
  jnc	@f
204
  pusha
205
  mov	cx, word [digital]
206
  and	cx, 1 shl 5
207
  shl	cx, 2
208
  add	cl, 56
209
  call	sendkey
210
  popa
211
@@:
212
 
213
  bt	ax, 11	  ; Start
214
  jnc	@f
215
  pusha
216
  mov	cx, word [digital]
217
  and	cx, 1 shl 11
218
  shr	cx, 4
219
  add	cl, 28
220
  call	sendkey
221
  popa
222
@@:
223
 
224
  bt	ax, 8	 ; Select
225
  jnc	@f
226
  pusha
227
  mov	cx, word [digital]
228
  and	cx, 1 shl 8
229
  shr	cx, 1
230
  add	cl, 14
231
  call	sendkey
232
  popa
233
@@:
234
 
235
  bt	ax, 12	  ; up
236
  jnc	@f
237
  pusha
238
  mov	cl, 224
239
  call	sendkey
240
  mov	cx, word [digital]
241
  and	cx, 1 shl 12
242
  shr	cx, 5
243
  add	cl, 72
244
  call	sendkey
245
  popa
246
@@:
247
 
248
  bt	ax, 13	  ; right
249
  jnc	@f
250
  pusha
251
  mov	cl, 224
252
  call	sendkey
253
  mov	cx, word [digital]
254
  and	cx, 1 shl 13
255
  shr	cx, 6
256
  add	cl, 77
257
  call	sendkey
258
  popa
259
@@:
260
 
261
  bt	ax, 14	  ; down
262
  jnc	@f
263
  pusha
264
  mov	cl, 224
265
  call	sendkey
266
  mov	cx, word [digital]
267
  and	cx, 1 shl 14
268
  shr	cx, 7
269
  add	cl, 80
270
  call	sendkey
271
  popa
272
@@:
273
 
274
  bt	ax, 15	  ; left
275
  jnc	@f
276
  pusha
277
  mov	cl, 224   ; extended key
278
  call	sendkey
279
  mov	cx, word [digital]
280
  and	cx, 1 shl 15
281
  shr	cx, 8
282
  add	cl, 75	  ; left
283
  call	sendkey
284
  popa
285
@@:
286
 
287
  mov	ax, word [digital]
288
  mov	word [digital_],ax
289
 
290
  call	raise_att
291
  jmp	mainloop
292
 
293
 
294
analog_red_controller:
295
  call	command_idle
296
  call	wait_for_ack
297
  ; Right now, we receive 0x5a from the controller, wich means: sending data!
298
;  DEBUGF 1,"Receiving data.. "
299
 
300
  call	command_idle
301
  call	wait_for_ack
302
  mov	byte [analog_red+5], bl
303
 
304
  call	command_idle
305
  call	wait_for_ack
306
  mov	byte [analog_red+4], bl
307
 
308
  call	command_idle
309
  call	wait_for_ack
310
  mov	byte [analog_red+3], bl
311
 
312
  call	command_idle
313
  call	wait_for_ack
314
  mov	byte [analog_red+2], bl
315
 
316
  call	command_idle
317
  call	wait_for_ack
318
  mov	byte [analog_red+1], bl
319
 
320
  call	command_idle
321
  mov	byte [analog_red+0], bl
322
 
323
 
324
;  DEBUGF 2,"Analog data: %x%x\n",[analog_red]:8,[analog_red+4]:4
325
  call	raise_att
326
  jmp	mainloop
327
 
328
 
329
 
330
 
331
exit:
332
  mov	eax, -1
333
  int	0x40
334
 
335
 
336
 
337
sendkey:	 ; This function inserts Keyboard Scan-codes into the kernel's queue
338
		 ; Scancode is in cl
339
;  mov	eax, 18
340
;  mov	ebx, 23
341
;  int	0x40
342
 
343
  pushad
344
 
345
  mov   eax, 72  ; <-- standart function (by Albom)
346
  mov   ebx, 1
347
  mov   edx, ecx
348
  and   edx, 0xff
349
  mov   ecx, 2
350
  int   0x40
351
 
352
  popad
353
  ret
354
 
355
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
356
;
357
;  Low-level code starts here
358
;
359
 
360
 
361
raise_att:
362
    mov  al, [PORT_DATA]
363
    bts  ax, attention
364
    mov  [PORT_DATA], al
365
 
366
    mov  dx, [BASE]
367
    out  dx, al
368
 
369
    ret
370
 
371
lower_att:
372
    mov  al, [PORT_DATA]
373
    btr  ax, attention
374
    mov  [PORT_DATA], al
375
 
376
    mov  dx, [BASE]
377
    out  dx, al
378
 
379
    ret
380
 
381
 
382
 
383
 
384
raise_clk:
385
    mov  al, [PORT_DATA]
386
    bts  ax, clock
387
    mov  [PORT_DATA], al
388
 
389
    mov  dx, [BASE]
390
    out  dx, al
391
 
392
    ret
393
 
394
lower_clk:
395
    mov  al, [PORT_DATA]
396
    btr  ax, clock
397
    mov  [PORT_DATA], al
398
 
399
    mov  dx, [BASE]
400
    out  dx, al
401
 
402
    ret
403
 
404
 
405
 
406
 
407
raise_vcc:
408
    mov  al, [PORT_DATA]
409
    or	 al, vcc
410
    mov  [PORT_DATA], al
411
 
412
    mov  dx, [BASE]
413
    out  dx, al
414
 
415
    ret
416
 
417
lower_vcc:
418
    mov  al, [PORT_DATA]
419
    and  al, 0xff - vcc
420
    mov  [PORT_DATA], al
421
 
422
    mov  dx, [BASE]
423
    out  dx, al
424
 
425
    ret
426
 
427
 
428
 
429
 
430
wait_for_ack:
431
    mov  dx, [STATUS]
432
    mov  ecx, 10000
433
.loop:
434
    in	 al, dx
435
    bt	 ax, ack
436
    jnc  .ack
437
    loop .loop
438
 
439
;    DEBUGF 2,"ACK timeout!\n"
440
 
441
;    pop  eax      ; balance the stack, we're not doing a ret like we should..
442
;    jmp  mainloop
443
 
444
.ack:
445
;    DEBUGF 1,"ACK !\n"
446
 
447
    ret
448
 
449
 
450
 
451
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
452
; This code comes from Serge's audio driver.
453
; If you know a better way to do 100 us wait, please tell me.
454
; This RDTSC stuff is know to have a bug in the newer AMD processors.
455
delay:
456
 
457
    push ecx
458
    push edx
459
    push ebx
460
    push eax
461
 
462
    mov  eax, 100
463
    mov  ecx, [CPUSPEED]
464
    mul  ecx
465
    mov  ebx, eax	;low
466
    mov  ecx, edx	;high
467
    rdtsc
468
    add  ebx, eax
469
    adc  ecx,edx
470
  @@:
471
    rdtsc
472
    sub  eax, ebx
473
    sbb  edx, ecx
474
    js	 @B
475
 
476
    pop  eax
477
    pop  ebx
478
    pop  edx
479
    pop  ecx
480
 
481
    ret
482
 
483
 
484
 
485
 
486
 
487
 
488
 
489
tx_rx:
490
    ; ah = byte to send
491
    ; bl = received byte
492
    mov  ecx, 8
493
    mov  bl, 0
494
 
495
tx_rx_loop:
496
    call delay
497
    call lower_clk
498
 
499
    mov  dl, ah
500
    and  dl, 1
501
;    DEBUGF 1,"OUTb:%u ", dl
502
 
503
    mov  al, [PORT_DATA]
504
    and  al, 0xfe
505
    or	 al, dl
506
    mov  [PORT_DATA], al
507
 
508
    mov  dx, [BASE]
509
    out  dx, al
510
 
511
    shr  ah, 1
512
 
513
    call delay
514
    call raise_clk
515
 
516
    mov  dx, [STATUS]
517
    in	 al, dx
518
 
519
    shl  al, 1
520
    and  al, 1 shl 7
521
;    DEBUGF 1,"INb:%x\n", al
522
    shr  bl, 1
523
    or	 bl, al
524
 
525
    loop tx_rx_loop
526
 
527
ret
528
 
529
 
530
 
531
command_idle:
532
    ; bl = received byte
533
    mov  bl, 0
534
    mov  ecx, 8
535
 
536
command_idle_loop:
537
    call delay
538
    call lower_clk
539
 
540
    call delay
541
    call raise_clk
542
 
543
    mov  dx, [STATUS]
544
    in	 al, dx
545
 
546
    shl  al, 1
547
    and  al, 1 shl 7
548
 
549
    shr  bl, 1
550
    or	 bl, al
551
 
552
    loop  command_idle_loop
553
 
554
ret
555
 
556
 
557
; DATA AREA
558
 
559
;include_debug_strings ; ALWAYS present in data section
560
 
561
; Addresses to PORT
562
BASE	    dw 0x378
563
STATUS	    dw 0x379
564
CONTROL     dw 0x37a
565
; Buffer for data port
566
PORT_DATA   db 0
567
 
568
; hmm, what would this be...
569
CPUSPEED    dd ?
570
 
571
; buffers for data from controller
572
digital     rb 2
573
digital_    rb 2   ; this buffer is used to find keychanges (if somebody just pressed/released a key)
574
analog_red  rb 6
575
analog_red_ rb 6
576
 
577
I_END: