forked from KolibriOS/kolibrios
psxpad src added.
git-svn-id: svn://kolibrios.org@1818 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
5646ab62dc
commit
3cdfb117d6
4
programs/system/psxpad/build.bat
Normal file
4
programs/system/psxpad/build.bat
Normal file
@ -0,0 +1,4 @@
|
||||
del psxpad
|
||||
fasm psxpad.asm psxpad
|
||||
kpack psxpad
|
||||
pause
|
577
programs/system/psxpad/psxpad.asm
Normal file
577
programs/system/psxpad/psxpad.asm
Normal file
@ -0,0 +1,577 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;
|
||||
; PSX-Pad for KolibriOS
|
||||
; Copyright (C) Jeffrey Amelynck 2008. All rights reserved.
|
||||
;
|
||||
; hidnplayr@kolibrios.org
|
||||
;
|
||||
; v0.1
|
||||
; date: 4/09/2008
|
||||
; type: private beta
|
||||
; functions implemented: Read raw data from Digital controller and Analog controller with red led.
|
||||
;
|
||||
; v0.2:
|
||||
; date: 5/09/2008
|
||||
; type: public beta
|
||||
; functions implemented: Same as above plus converting keycodes from keypad do keyboard scancodes.
|
||||
; : To use this function you need a kernel wich can input scancodes using function 18,23.
|
||||
; ; I also did some cleanup and speedup
|
||||
;
|
||||
;
|
||||
; v0.2.1
|
||||
; by O. Bogomaz aka Albom, albom85@yandex.ru
|
||||
; using of standart kernel function 72.1
|
||||
;
|
||||
;
|
||||
; TODO: - Multiple controllers
|
||||
; - Analog controller(s)
|
||||
;
|
||||
;
|
||||
; More info about PSX/PS2 gamepad protocol:
|
||||
; http://curiousinventor.com/guides/ps2
|
||||
; http://www.geocities.com/digitan000/Hardware/22/e22_page.html
|
||||
;
|
||||
; How to connect your PSX pad to the PC:
|
||||
; http://www.emulatronia.com/reportajes/directpad/psxeng/print.htm
|
||||
;
|
||||
;
|
||||
; PSX-Pad for KolibriOS is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY.
|
||||
; No author or distributor accepts responsibility to anyone for the
|
||||
; consequences of using it or for whether it serves any particular purpose or
|
||||
; works at all, unless he says so in writing. Refer to the GNU General Public
|
||||
; License (the "GPL") for full details.
|
||||
;
|
||||
; Everyone is granted permission to copy, modify and redistribute KolibriOS,
|
||||
; but only under the conditions described in the GPL. A copy of this license
|
||||
; is supposed to have been given to you along with KolibriOS so you can know
|
||||
; your rights and responsibilities. It should be in a file named COPYING.
|
||||
; Among other things, the copyright notice and this notice must be preserved
|
||||
; on all copies.
|
||||
;
|
||||
|
||||
use32
|
||||
|
||||
org 0x0
|
||||
|
||||
db 'MENUET01' ; 8 byte id
|
||||
dd 0x01 ; header version
|
||||
dd START ; start of code
|
||||
dd I_END ; size of image
|
||||
dd 0x100000 ; memory for app
|
||||
dd 0x100000 ; esp
|
||||
dd 0x0 , 0x0 ; I_Param , I_Icon
|
||||
|
||||
; Bits on Data Port (outputs for pc)
|
||||
command equ 0
|
||||
attention equ 1
|
||||
clock equ 2
|
||||
vcc equ (1 shl 3 + 1 shl 4 + 1 shl 5 + 1 shl 6 + 1 shl 7)
|
||||
|
||||
; Bits on Status Port (inputs for PC)
|
||||
data equ 6
|
||||
ack equ 5
|
||||
|
||||
__DEBUG__ equ 1
|
||||
__DEBUG_LEVEL__ equ 2
|
||||
|
||||
include '../../macros.inc'
|
||||
;include 'fdo.inc'
|
||||
|
||||
START:
|
||||
mov eax, 40 ; Disable notification of all events
|
||||
xor ebx, ebx
|
||||
int 0x40
|
||||
|
||||
; DEBUGF 2,"\nPSX-Pad for KolibriOS v0.2\n\n"
|
||||
|
||||
mov eax, 46 ; Ask the kernel if wse may use the LPT port
|
||||
mov ebx, 0
|
||||
movzx ecx, [BASE]
|
||||
movzx edx, [CONTROL]
|
||||
int 0x40
|
||||
test eax, eax
|
||||
jz @f
|
||||
|
||||
; DEBUGF 2,"Could not reserve port!\n"
|
||||
jmp exit
|
||||
@@:
|
||||
|
||||
mov dx, [CONTROL] ; disable bi-directional data port
|
||||
in al, dx
|
||||
and al, 0xdf
|
||||
out dx, al
|
||||
|
||||
mov eax, 18 ; read CPU-speed, we'll need it for 100us delay
|
||||
mov ebx, 5
|
||||
int 0x40 ; now we've got the cpuspeed in hz, we need it in Mhz
|
||||
xor edx, edx
|
||||
mov ecx, 1000000
|
||||
div ecx
|
||||
mov [CPUSPEED], eax
|
||||
; DEBUGF 2,"CPUspeed: %u\n",eax
|
||||
|
||||
; DEBUGF 1,"Raising attention line\n"
|
||||
call raise_att
|
||||
|
||||
; DEBUGF 1,"Raising Clock\n"
|
||||
call raise_clk
|
||||
|
||||
; DEBUGF 1,"Powering Up controller\n"
|
||||
call raise_vcc
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;
|
||||
; All things are ready to go, enter mainloop!
|
||||
;
|
||||
; This loop constantly poll's the PSX-pad for data
|
||||
;
|
||||
|
||||
mainloop:
|
||||
|
||||
mov eax, 5 ; Lets start by giving the other applications some cpu time, we'll take ours later.
|
||||
mov ebx, 5
|
||||
int 0x40
|
||||
|
||||
; DEBUGF 1,"Lowering attention line\n"
|
||||
call lower_att ; We've got the attention from the PSX-Pad now :) (yes, it's active low..)
|
||||
|
||||
; DEBUGF 1,"Sending Startup byte.. "
|
||||
mov ah, 0x01 ; Startup code
|
||||
call tx_rx
|
||||
call wait_for_ack
|
||||
; DEBUGF 1,"Rx: %x\n",bl
|
||||
|
||||
; DEBUGF 1,"Request for data.. "
|
||||
mov ah, 0x42 ; Request for data
|
||||
call tx_rx
|
||||
call wait_for_ack
|
||||
; DEBUGF 1,"Rx: %x\n",bl
|
||||
|
||||
cmp bl, 0x41
|
||||
je digital_controller
|
||||
|
||||
cmp bl, 0x73
|
||||
je analog_red_controller
|
||||
|
||||
; cmp ah, 0x23
|
||||
; je negcon_controller
|
||||
|
||||
; cmp ah, 0x53
|
||||
; je analog_green_controller
|
||||
|
||||
; cmp ah, 0x12
|
||||
; je psx_mouse
|
||||
|
||||
|
||||
; DEBUGF 2,"Unsupported controller/mode:%x !\n",bl
|
||||
jmp exit
|
||||
|
||||
|
||||
|
||||
|
||||
digital_controller:
|
||||
call command_idle
|
||||
call wait_for_ack
|
||||
; Right now, we receive 0x5a from the controller, wich means: sending data!
|
||||
; DEBUGF 1,"Receiving data.. "
|
||||
|
||||
call command_idle
|
||||
call wait_for_ack
|
||||
mov byte [digital+1], bl
|
||||
|
||||
call command_idle
|
||||
mov byte [digital+0], bl
|
||||
|
||||
; DEBUGF 1,"Digital data: %x\n",[digital]:4
|
||||
|
||||
mov ax, word [digital_]
|
||||
xor ax, word [digital]
|
||||
mov cx, word [digital]
|
||||
|
||||
bt ax, 6 ; X
|
||||
jnc @f
|
||||
pusha
|
||||
and cx, 1 shl 6
|
||||
shl cx, 1
|
||||
add cl, 29
|
||||
call sendkey
|
||||
popa
|
||||
@@:
|
||||
|
||||
bt ax, 5 ; O
|
||||
jnc @f
|
||||
pusha
|
||||
mov cx, word [digital]
|
||||
and cx, 1 shl 5
|
||||
shl cx, 2
|
||||
add cl, 56
|
||||
call sendkey
|
||||
popa
|
||||
@@:
|
||||
|
||||
bt ax, 11 ; Start
|
||||
jnc @f
|
||||
pusha
|
||||
mov cx, word [digital]
|
||||
and cx, 1 shl 11
|
||||
shr cx, 4
|
||||
add cl, 28
|
||||
call sendkey
|
||||
popa
|
||||
@@:
|
||||
|
||||
bt ax, 8 ; Select
|
||||
jnc @f
|
||||
pusha
|
||||
mov cx, word [digital]
|
||||
and cx, 1 shl 8
|
||||
shr cx, 1
|
||||
add cl, 14
|
||||
call sendkey
|
||||
popa
|
||||
@@:
|
||||
|
||||
bt ax, 12 ; up
|
||||
jnc @f
|
||||
pusha
|
||||
mov cl, 224
|
||||
call sendkey
|
||||
mov cx, word [digital]
|
||||
and cx, 1 shl 12
|
||||
shr cx, 5
|
||||
add cl, 72
|
||||
call sendkey
|
||||
popa
|
||||
@@:
|
||||
|
||||
bt ax, 13 ; right
|
||||
jnc @f
|
||||
pusha
|
||||
mov cl, 224
|
||||
call sendkey
|
||||
mov cx, word [digital]
|
||||
and cx, 1 shl 13
|
||||
shr cx, 6
|
||||
add cl, 77
|
||||
call sendkey
|
||||
popa
|
||||
@@:
|
||||
|
||||
bt ax, 14 ; down
|
||||
jnc @f
|
||||
pusha
|
||||
mov cl, 224
|
||||
call sendkey
|
||||
mov cx, word [digital]
|
||||
and cx, 1 shl 14
|
||||
shr cx, 7
|
||||
add cl, 80
|
||||
call sendkey
|
||||
popa
|
||||
@@:
|
||||
|
||||
bt ax, 15 ; left
|
||||
jnc @f
|
||||
pusha
|
||||
mov cl, 224 ; extended key
|
||||
call sendkey
|
||||
mov cx, word [digital]
|
||||
and cx, 1 shl 15
|
||||
shr cx, 8
|
||||
add cl, 75 ; left
|
||||
call sendkey
|
||||
popa
|
||||
@@:
|
||||
|
||||
mov ax, word [digital]
|
||||
mov word [digital_],ax
|
||||
|
||||
call raise_att
|
||||
jmp mainloop
|
||||
|
||||
|
||||
analog_red_controller:
|
||||
call command_idle
|
||||
call wait_for_ack
|
||||
; Right now, we receive 0x5a from the controller, wich means: sending data!
|
||||
; DEBUGF 1,"Receiving data.. "
|
||||
|
||||
call command_idle
|
||||
call wait_for_ack
|
||||
mov byte [analog_red+5], bl
|
||||
|
||||
call command_idle
|
||||
call wait_for_ack
|
||||
mov byte [analog_red+4], bl
|
||||
|
||||
call command_idle
|
||||
call wait_for_ack
|
||||
mov byte [analog_red+3], bl
|
||||
|
||||
call command_idle
|
||||
call wait_for_ack
|
||||
mov byte [analog_red+2], bl
|
||||
|
||||
call command_idle
|
||||
call wait_for_ack
|
||||
mov byte [analog_red+1], bl
|
||||
|
||||
call command_idle
|
||||
mov byte [analog_red+0], bl
|
||||
|
||||
|
||||
; DEBUGF 2,"Analog data: %x%x\n",[analog_red]:8,[analog_red+4]:4
|
||||
call raise_att
|
||||
jmp mainloop
|
||||
|
||||
|
||||
|
||||
|
||||
exit:
|
||||
mov eax, -1
|
||||
int 0x40
|
||||
|
||||
|
||||
|
||||
sendkey: ; This function inserts Keyboard Scan-codes into the kernel's queue
|
||||
; Scancode is in cl
|
||||
; mov eax, 18
|
||||
; mov ebx, 23
|
||||
; int 0x40
|
||||
|
||||
pushad
|
||||
|
||||
mov eax, 72 ; <-- standart function (by Albom)
|
||||
mov ebx, 1
|
||||
mov edx, ecx
|
||||
and edx, 0xff
|
||||
mov ecx, 2
|
||||
int 0x40
|
||||
|
||||
popad
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;
|
||||
; Low-level code starts here
|
||||
;
|
||||
|
||||
|
||||
raise_att:
|
||||
mov al, [PORT_DATA]
|
||||
bts ax, attention
|
||||
mov [PORT_DATA], al
|
||||
|
||||
mov dx, [BASE]
|
||||
out dx, al
|
||||
|
||||
ret
|
||||
|
||||
lower_att:
|
||||
mov al, [PORT_DATA]
|
||||
btr ax, attention
|
||||
mov [PORT_DATA], al
|
||||
|
||||
mov dx, [BASE]
|
||||
out dx, al
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
raise_clk:
|
||||
mov al, [PORT_DATA]
|
||||
bts ax, clock
|
||||
mov [PORT_DATA], al
|
||||
|
||||
mov dx, [BASE]
|
||||
out dx, al
|
||||
|
||||
ret
|
||||
|
||||
lower_clk:
|
||||
mov al, [PORT_DATA]
|
||||
btr ax, clock
|
||||
mov [PORT_DATA], al
|
||||
|
||||
mov dx, [BASE]
|
||||
out dx, al
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
raise_vcc:
|
||||
mov al, [PORT_DATA]
|
||||
or al, vcc
|
||||
mov [PORT_DATA], al
|
||||
|
||||
mov dx, [BASE]
|
||||
out dx, al
|
||||
|
||||
ret
|
||||
|
||||
lower_vcc:
|
||||
mov al, [PORT_DATA]
|
||||
and al, 0xff - vcc
|
||||
mov [PORT_DATA], al
|
||||
|
||||
mov dx, [BASE]
|
||||
out dx, al
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
wait_for_ack:
|
||||
mov dx, [STATUS]
|
||||
mov ecx, 10000
|
||||
.loop:
|
||||
in al, dx
|
||||
bt ax, ack
|
||||
jnc .ack
|
||||
loop .loop
|
||||
|
||||
; DEBUGF 2,"ACK timeout!\n"
|
||||
|
||||
; pop eax ; balance the stack, we're not doing a ret like we should..
|
||||
; jmp mainloop
|
||||
|
||||
.ack:
|
||||
; DEBUGF 1,"ACK !\n"
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; This code comes from Serge's audio driver.
|
||||
; If you know a better way to do 100 us wait, please tell me.
|
||||
; This RDTSC stuff is know to have a bug in the newer AMD processors.
|
||||
delay:
|
||||
|
||||
push ecx
|
||||
push edx
|
||||
push ebx
|
||||
push eax
|
||||
|
||||
mov eax, 100
|
||||
mov ecx, [CPUSPEED]
|
||||
mul ecx
|
||||
mov ebx, eax ;low
|
||||
mov ecx, edx ;high
|
||||
rdtsc
|
||||
add ebx, eax
|
||||
adc ecx,edx
|
||||
@@:
|
||||
rdtsc
|
||||
sub eax, ebx
|
||||
sbb edx, ecx
|
||||
js @B
|
||||
|
||||
pop eax
|
||||
pop ebx
|
||||
pop edx
|
||||
pop ecx
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
tx_rx:
|
||||
; ah = byte to send
|
||||
; bl = received byte
|
||||
mov ecx, 8
|
||||
mov bl, 0
|
||||
|
||||
tx_rx_loop:
|
||||
call delay
|
||||
call lower_clk
|
||||
|
||||
mov dl, ah
|
||||
and dl, 1
|
||||
; DEBUGF 1,"OUTb:%u ", dl
|
||||
|
||||
mov al, [PORT_DATA]
|
||||
and al, 0xfe
|
||||
or al, dl
|
||||
mov [PORT_DATA], al
|
||||
|
||||
mov dx, [BASE]
|
||||
out dx, al
|
||||
|
||||
shr ah, 1
|
||||
|
||||
call delay
|
||||
call raise_clk
|
||||
|
||||
mov dx, [STATUS]
|
||||
in al, dx
|
||||
|
||||
shl al, 1
|
||||
and al, 1 shl 7
|
||||
; DEBUGF 1,"INb:%x\n", al
|
||||
shr bl, 1
|
||||
or bl, al
|
||||
|
||||
loop tx_rx_loop
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
command_idle:
|
||||
; bl = received byte
|
||||
mov bl, 0
|
||||
mov ecx, 8
|
||||
|
||||
command_idle_loop:
|
||||
call delay
|
||||
call lower_clk
|
||||
|
||||
call delay
|
||||
call raise_clk
|
||||
|
||||
mov dx, [STATUS]
|
||||
in al, dx
|
||||
|
||||
shl al, 1
|
||||
and al, 1 shl 7
|
||||
|
||||
shr bl, 1
|
||||
or bl, al
|
||||
|
||||
loop command_idle_loop
|
||||
|
||||
ret
|
||||
|
||||
|
||||
; DATA AREA
|
||||
|
||||
;include_debug_strings ; ALWAYS present in data section
|
||||
|
||||
; Addresses to PORT
|
||||
BASE dw 0x378
|
||||
STATUS dw 0x379
|
||||
CONTROL dw 0x37a
|
||||
; Buffer for data port
|
||||
PORT_DATA db 0
|
||||
|
||||
; hmm, what would this be...
|
||||
CPUSPEED dd ?
|
||||
|
||||
; buffers for data from controller
|
||||
digital rb 2
|
||||
digital_ rb 2 ; this buffer is used to find keychanges (if somebody just pressed/released a key)
|
||||
analog_red rb 6
|
||||
analog_red_ rb 6
|
||||
|
||||
I_END:
|
5
programs/system/psxpad/readme.txt
Normal file
5
programs/system/psxpad/readme.txt
Normal file
@ -0,0 +1,5 @@
|
||||
PSX-Pad for KolibriOS
|
||||
v0.2.1
|
||||
|
||||
Изменённая программа для работы с джойпадом от Sony Playstation.
|
||||
В отличии от оригинальной версии, не требуется нестандартное ядро (с функцией 18.23).
|
BIN
programs/system/psxpad/scheme.png
Normal file
BIN
programs/system/psxpad/scheme.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Loading…
Reference in New Issue
Block a user