From 538f28cfbbbb8163ab8a96de77d6887123856c81 Mon Sep 17 00:00:00 2001 From: Lameguy64 Date: Mon, 25 Oct 2021 10:51:50 +0800 Subject: Added indev directory --- indev/psxpad/pad.s | 264 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 indev/psxpad/pad.s (limited to 'indev/psxpad/pad.s') 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 + + -- cgit v1.2.3