diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-07-05 02:34:11 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2025-07-05 02:34:11 +0200 |
| commit | beb76e4dd362374b8f42cd971d394bba1074cd8d (patch) | |
| tree | 3ea4cc342737afb9225c01160c92647ba66c78bd /indev/psxpad/pad.S | |
| parent | 5d9aa2d3dfc7d6e51c2eb942ab4cdbae5571a40a (diff) | |
| download | psn00bsdk-fix-include.tar.gz | |
Replace .include with #includefix-include
For some reason, both mipsel-unknown-elf-gcc 8.2.0 and mipsel-non-elf
15.1.0 were unable to resolve .include assembler directives.
As a workaround, it is still possible to use the preprocessor, and
therefore the usual #include preprocessor directive. However, this
requires the assembly files to use the uppercase .S file extension.
Diffstat (limited to 'indev/psxpad/pad.S')
| -rw-r--r-- | indev/psxpad/pad.S | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/indev/psxpad/pad.S b/indev/psxpad/pad.S new file mode 100644 index 0000000..0fa66aa --- /dev/null +++ b/indev/psxpad/pad.S @@ -0,0 +1,264 @@ +.set noreorder
+
+.include "hwregs_a.h"
+
+.section .text
+
+.global _InitPadDirect
+.type _InitPadDirect, @function
+_InitPadDirect:
+
+ addiu $sp, -4
+ sw $ra, 0($sp)
+
+ lui $t0, IOBASE
+
+ # Interface setup
+ li $v0, 0x40 # Interface reset
+ sh $v0, JOY_CTRL($t0)
+ li $v0, 0x88 # 250kHz clock rate
+ sh $v0, JOY_BAUD($t0)
+ li $v0, 0x0d # 8-bit, no parity, x1 multiplier
+ sh $v0, JOY_MODE($t0)
+ li $v0, 0x1003 # JOY1, TX enabled
+ sh $v0, JOY_CTRL($t0)
+
+ jal _wait
+ li $v0, 1000
+
+ # Empty RX fifo
+.Lempty_fifo:
+ lbu $v1, JOY_TXRX($t0)
+ lhu $v0, JOY_STAT($t0)
+ nop
+ andi $v0, 0x2
+ bnez $v0, .Lempty_fifo
+ nop
+
+ lw $ra, 0($sp)
+ addiu $sp, 4
+ jr $ra
+ nop
+
+
+.global _PadSetPort
+.type _PadSetPort, @function
+_PadSetPort:
+ addiu $sp, -4
+ sw $ra, 0($sp)
+
+ lui $t0, IOBASE
+
+ beq $a0, 2, .Lstop_comms
+ nop
+
+ li $v0, 0x1003 # TX Enable, Joypad port select
+ andi $a0, 1
+ sll $a0, 13
+ or $v0, $a0 # Select port 2 if a0 is 1
+
+ sh $v0, JOY_CTRL($t0) # Set to Joypad control interface
+
+ jal _wait # Delay for analog pads (needs testing)
+ li $v0, 500
+
+.Lread_empty_fifo_set: # Flush the RX FIFO just in case
+ lbu $v1, JOY_TXRX($t0)
+ lhu $v0, JOY_STAT($t0)
+ nop
+ andi $v0, 0x2
+ bnez $v0, .Lread_empty_fifo_set
+ nop
+
+ lw $ra, 0($sp)
+ addiu $sp, 4
+ jr $ra
+ nop
+
+.Lstop_comms:
+
+ sh $0 , JOY_CTRL($t0)
+
+ lw $ra, 0($sp)
+ addiu $sp, 4
+ jr $ra
+ nop
+
+
+.global _PadReadDirect
+.type _PadReadDirect, @function
+_PadReadDirect:
+
+ # a0 - port number
+ # a1 - device data buffer
+ # a2 - data max length
+
+ addiu $sp, -4
+ sw $ra, 0($sp)
+
+ lui $t0, IOBASE
+
+ li $v0, 0x1003 # TX Enable, Joypad port select
+ andi $a0, 1
+ sll $a0, 13
+ or $v0, $a0 # Select port 2 if a0 is 1
+
+ sh $v0, JOY_CTRL($t0) # Set to Joypad control interface
+
+ jal _wait # Delay for analog pads (needs testing)
+ li $v0, 310
+
+# May cause issues with third party adapters such as Brook wireless
+#.Lread_empty_fifo: # Flush the RX FIFO just in case
+# lbu $v1, JOY_TXRX($t0)
+# lhu $v0, JOY_STAT($t0)
+# nop
+# andi $v0, 0x2
+# bnez $v0, .Lread_empty_fifo
+# nop
+
+ jal _PadExchng # Send device check byte
+ li $a0, 0x01
+
+ andi $v1, $v0, 0x100 # No pad if exchange timed out
+ bnez $v1, .Lno_device
+ addiu $v0, $0 , 1
+
+ sb $v0, 0($a1)
+ addiu $a1, 1
+
+ jal _wait # 1st exchange needs 27microsec after ACK
+ li $v0, 190 # (e.g. 7 as usual + an extra 20)
+
+ jal _PadExchng # Send command byte
+ li $a0, 0x42
+
+ sb $v0, 0($a1)
+ addiu $a1, 1
+ addiu $a2, -2
+
+ jal _PadExchng # Send 0 for pads, 1 for multitap
+ move $a0, $0 # Read is usually 0x5A
+
+ addi $a3, $0 , 1
+
+ la $t1, _pad_mot_values
+
+.Lread_loop: # Read until buffer full, or no more data
+
+ lbu $a0, 0($t1)
+ nop
+ beqz $a0, .Lskip_mot
+ nop
+
+ jal _PadExchng
+ nop
+
+ b .Ldone_exchg
+ addiu $t1, 1
+
+.Lskip_mot:
+
+ jal _PadExchng # when ACK is no longer triggered
+ move $a0, $0
+
+.Ldone_exchg:
+
+ sb $v0, 0($a1)
+
+ andi $v0, 0x100
+ bnez $v0, .Lread_end
+ addi $a3, 1
+
+ addiu $a2, -1
+ bgtz $a2, .Lread_loop
+ addiu $a1, 1
+
+.Lread_end:
+
+ b .Lexit
+ move $v0, $a3
+
+.Lno_device:
+
+ addiu $v0, $0 , -1
+ sb $v0, 0($a1)
+
+.Lexit:
+
+ sh $0 , JOY_CTRL($t0)
+
+ lw $ra, 0($sp)
+ addiu $sp, 4
+ jr $ra
+ nop
+
+
+.global _PadExchng
+.type _PadExchng, @function
+_PadExchng:
+
+ lui $t0, IOBASE
+
+ sb $a0, JOY_TXRX($t0)
+ nop
+.Lsend_wait:
+ lhu $v0, JOY_STAT($t0)
+ nop
+ andi $v0, 0x4
+ beqz $v0, .Lsend_wait
+ nop
+
+ move $v1, $0
+.Lwait_ack:
+ bgt $v1, 100, .Ltimeout
+ lhu $v0, JOY_STAT($t0)
+ nop
+ andi $v0, 0x202
+ bne $v0, 0x202, .Lwait_ack
+ addiu $v1, 1
+
+ b .Ldone
+ nop
+
+.Ltimeout:
+
+ lbu $v0, JOY_TXRX($t0)
+ nop
+ b .Lexit_exchg
+ ori $v0, 0x100
+
+.Ldone:
+
+ lhu $v1, JOY_CTRL($t0)
+ lbu $v0, JOY_TXRX($t0)
+ or $v1, 0x10
+ sh $v1, JOY_CTRL($t0)
+
+.Lexit_exchg:
+
+ jr $ra
+ nop
+
+
+.global _wait
+.type _wait, @function
+_wait:
+ addiu $v0, -1
+ bgtz $v0, _wait
+ nop
+ jr $ra
+ nop
+
+
+.section .data
+
+.global _pad_mot_values
+.type _pad_mot_values, @object
+_pad_mot_values:
+ .byte 0 # Small motor
+ .byte 0 # Big motor
+ .byte 0
+ .byte 0
+
+
|
