Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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:
  578.