aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b/libpsxcd/psxcd_asm.s
diff options
context:
space:
mode:
Diffstat (limited to 'libpsn00b/libpsxcd/psxcd_asm.s')
-rw-r--r--libpsn00b/libpsxcd/psxcd_asm.s520
1 files changed, 520 insertions, 0 deletions
diff --git a/libpsn00b/libpsxcd/psxcd_asm.s b/libpsn00b/libpsxcd/psxcd_asm.s
new file mode 100644
index 0000000..7fe1c1d
--- /dev/null
+++ b/libpsn00b/libpsxcd/psxcd_asm.s
@@ -0,0 +1,520 @@
+.set noreorder
+
+.include "hwregs_a.h"
+
+.section .text
+
+.global _cd_init
+.type _cd_init, @function
+_cd_init:
+
+ addiu $sp, -4
+ sw $ra, 0($sp)
+
+ jal EnterCriticalSection
+ nop
+
+ lui $a3, IOBASE # Acknowledge all CD IRQs
+ li $v0, 1
+ sb $v0, CD_REG0($a3)
+ li $v0, 0x1f
+ sb $v0, CD_REG3($a3)
+ sb $v0, CD_REG2($a3) # Enable all IRQs
+
+ sb $0 , CD_REG0($a3)
+ sb $0 , CD_REG3($a3)
+
+ li $v0, 0x1325
+ sw $v0, COM_DELAY($a3)
+
+ la $a1, _cd_handler
+ jal InterruptCallback
+ li $a0, 2
+
+ li $v0, 2 # Set CD left volume
+ sb $v0, CD_REG0($a3)
+ li $v0, 0x80
+ sb $v0, CD_REG2($a3)
+
+ li $v0, 3 # Set CD right volume
+ sb $v0, CD_REG0($a3)
+ li $v0, 0x80
+ sb $v0, CD_REG1($a3)
+
+ li $v0, 0x20 # Apply volume
+ sb $v0, CD_REG3($a3)
+
+ # Clear a bunch of stats
+ la $v0, _cd_ack_wait
+ sb $0 , 0($v0)
+ la $v0, _cd_complt_wait
+ sb $0 , 0($v0)
+ la $v0, _cd_last_cmd
+ sb $0 , 0($v0)
+ la $v0, _cd_last_mode
+ sb $0 , 0($v0)
+ la $v0, _cd_last_int
+ sb $0 , 0($v0)
+
+ la $v0, _cd_result_ptr
+ sw $0 , 0($v0)
+
+ # Clear callback hooks
+ la $v0, _cd_callback_int1_data
+ sw $0 , 0($v0)
+ la $v0, _cd_callback_int4
+ sw $0 , 0($v0)
+
+ la $v0, _cd_read_cb
+ sw $0 , 0($v0)
+
+ lw $v0, DPCR($a3)
+ li $v1, 0xB000
+ or $v0, $v1
+ sw $v0, DPCR($a3)
+
+ jal ExitCriticalSection
+ nop
+
+ #li $a0, 0x01 # GetStat
+ #jal _cd_control
+ #move $a2, $0
+ #jal _cd_wait
+ #nop
+
+ #li $a0, 0x0a # Init
+ #jal _cd_control
+ #move $a2, $0
+ #jal _cd_wait
+ #nop
+
+ #li $a0, 0x0c # Demute
+ #jal _cd_control
+ #move $a2, $0
+ #jal _cd_wait
+ #nop
+
+ #la $a0, _cd_init_msg
+ #jal printf
+ #addiu $sp, -16
+ #addiu $sp, 16
+
+ lw $ra, 0($sp)
+ addiu $sp, 4
+ jr $ra
+ nop
+
+
+.global _cd_wait
+.type _cd_wait, @function
+_cd_wait:
+ la $v0, _cd_ack_wait
+ lbu $v0, 0($v0)
+ nop
+ bnez $v0, _cd_wait
+ nop
+.Lcomplete:
+ la $v0, _cd_complt_wait
+ lbu $v0, 0($v0)
+ nop
+ bnez $v0, .Lcomplete
+ nop
+ jr $ra
+ nop
+
+
+.global _cd_wait_ack
+.type _cd_wait_ack, @function
+_cd_wait_ack:
+ la $v0, _cd_ack_wait
+ lbu $v0, 0($v0)
+ nop
+ bnez $v0, _cd_wait_ack
+ nop
+ jr $ra
+ nop
+
+
+.global _cd_wait_complt
+.type _cd_wait_complt, @function
+_cd_wait_complt:
+ la $v0, _cd_complt_wait
+ lbu $v0, 0($v0)
+ nop
+ bnez $v0, _cd_wait_complt
+ nop
+ jr $ra
+ nop
+
+
+.type _cd_handler, @function
+_cd_handler:
+
+ addiu $sp, -4
+ sw $ra, 0($sp)
+
+ lui $a3, IOBASE # Print out IRQ number
+ li $v0, 1
+ sb $v0, CD_REG0($a3)
+
+ lbu $v0, CD_REG3($a3)
+ nop
+ andi $v0, 0x7
+
+ la $v1, _cd_last_int # Save last IRQ value
+ sb $v0, 0($v1)
+
+ bne $v0, 0x1, .Lno_data
+ nop
+
+ sb $0 , CD_REG0($a3) # Load data FIFO on INT1
+ li $v1, 0x80
+ sb $v1, CD_REG3($a3)
+
+.Lno_data:
+
+ li $v1, 1
+ sb $v1, CD_REG0($a3) # Clear CD interrupt and parameter FIFO
+ li $v1, 0x5f
+ sb $v1, CD_REG3($a3)
+ li $v1, 0x40
+ sb $v1, CD_REG3($a3)
+
+ li $v1, 0 # Delay when clearing parameter FIFO
+ sw $v1, 0($0)
+ li $v1, 1
+ sw $v1, 0($0)
+ li $v1, 2
+ sw $v1, 0($0)
+ li $v1, 3
+ sw $v1, 0($0)
+
+ beq $v0, 0x1, .Lirq_1 # Data ready
+ nop
+ beq $v0, 0x2, .Lirq_2 # Command finish
+ nop
+ beq $v0, 0x3, .Lirq_3 # Acknowledge
+ nop
+ beq $v0, 0x4, .Lirq_4 # Data/track end
+ nop
+ beq $v0, 0x5, .Lirq_5 # Error
+ nop
+
+ b .Lirq_misc
+ nop
+
+.Lirq_1: # Data ready
+
+ jal _cd_fetch_result
+ nop
+
+ la $v0, _cd_callback_int1_data
+ lw $v0, 0($v0)
+ nop
+ beqz $v0, .Lirq_misc
+ nop
+
+ la $a0, _cd_last_int
+ lbu $a0, 0($a0)
+ la $a1, _cd_result_ptr
+ lw $a1, 0($a1)
+
+ jalr $v0
+ addiu $sp, -16
+ addiu $sp, 16
+
+ b .Lirq_misc
+ nop
+
+.Lirq_2: # Command complete
+
+ jal _cd_fetch_result
+ nop
+
+ la $v0, _cd_complt_wait
+ sb $0 , 0($v0)
+
+ la $v0, _cd_sync_cb
+ lw $v0, 0($v0)
+ nop
+ beqz $v0, .Lirq_misc
+ nop
+
+ la $a0, _cd_last_int
+ lbu $a0, 0($a0)
+ la $a1, _cd_result_ptr
+ lw $a1, 0($a1)
+ jalr $v0
+ addiu $sp, -16
+ addiu $sp, 16
+
+ b .Lirq_misc
+ nop
+
+.Lirq_3: # Command acknowledge
+
+ jal _cd_fetch_result
+ nop
+
+ la $v0, _cd_ack_wait
+ sb $0 , 0($v0)
+
+ b .Lirq_misc
+ nop
+
+.Lirq_4:
+
+ jal _cd_fetch_result
+ nop
+
+ la $v0, _cd_callback_int4
+ lw $v0, 0($v0)
+ nop
+ beqz $v0, .Lirq_misc
+ nop
+
+ jalr $v0
+ addiu $sp, -16
+ addiu $sp, 16
+
+ b .Lirq_misc
+ nop
+
+.Lirq_5: # Error
+
+ jal _cd_fetch_result
+ nop
+
+ la $v0, _cd_complt_wait
+ lbu $v0, 0($v0)
+ nop
+ beqz $v0, .Lno_complete
+ nop
+
+ la $v0, _cd_sync_cb
+ lw $v0, 0($v0)
+ nop
+ beqz $v0, .Lno_complete
+ nop
+
+ li $a0, 0x05 # CdlDiskError
+ la $a1, _cd_result_ptr
+ lw $a1, 0($a1)
+ jalr $v0
+ addiu $sp, -16
+ addiu $sp, 16
+
+.Lno_complete:
+
+ la $v0, _cd_complt_wait
+ sb $0 , 0($v0)
+ la $v0, _cd_ack_wait
+ sb $0 , 0($v0)
+
+ la $v0, _cd_callback_int1_data
+ lw $v0, 0($v0)
+ nop
+ beqz $v0, .Lirq_misc
+ nop
+
+ li $a0, 0x05 # CdlDiskError
+ la $a1, _cd_result_ptr
+ lw $a1, 0($a1)
+
+ jalr $v0
+ addiu $sp, -16
+ addiu $sp, 16
+
+.Lirq_misc:
+
+ lw $ra, 0($sp)
+ addiu $sp, 4
+ jr $ra
+ nop
+
+
+_cd_fetch_result:
+
+ lui $a3, IOBASE
+
+ la $a0, _cd_status
+ lbu $v0, CD_REG1($a3)
+
+ la $v1, _cd_last_int
+ lbu $v1, 0($v1)
+ nop
+ beq $v1, 0x2, .Lirq2_checks
+ nop
+
+ # IRQ3 checks
+
+ la $v1, _cd_last_cmd
+ lbu $v1, 0($v1)
+ nop
+ beq $v1, 0x10, .Lskip_status
+ nop
+ beq $v1, 0x11, .Lskip_status
+ nop
+
+ b .Lwrite_status
+ nop
+
+ # IRQ2 checks
+
+.Lirq2_checks:
+
+ la $v1, _cd_last_cmd
+ lbu $v1, 0($v1)
+ nop
+ beq $v1, 0x1D, .Lskip_status
+ nop
+
+.Lwrite_status:
+
+ sb $v0, 0($a0)
+
+.Lskip_status:
+
+ la $a0, _cd_result_ptr
+ lw $a0, 0($a0)
+ nop
+ beqz $a0, .Lno_result
+ nop
+ sb $v0, 0($a0)
+ addiu $a0, 1
+
+.Lread_futher_result:
+
+ lbu $v0, CD_REG0($a3)
+ nop
+ andi $v0, 0x20
+ beqz $v0, .Lno_result
+ nop
+
+ lbu $v0, CD_REG1($a3)
+ lbu $v1, CD_REG0($a3)
+ sb $v0, 0($a0)
+ andi $v1, 0x20
+ bnez $v1, .Lread_futher_result
+ addiu $a0, 1
+
+.Lno_result:
+
+ jr $ra
+ nop
+
+
+.global CdAutoPauseCallback
+.type CdAutoPauseCallback, @function
+CdAutoPauseCallback:
+
+ addiu $sp, -8
+ sw $ra, 0($sp)
+ sw $a0, 4($sp)
+
+ la $v1, _cd_callback_int4
+ lw $v0, 0($v1)
+
+ la $v1, _cd_callback_int4
+
+ jal EnterCriticalSection
+ nop
+
+ lw $a0, 4($sp)
+ nop
+ sw $a0, 0($v1)
+
+ jal ExitCriticalSection
+ nop
+
+ lw $ra, 0($sp)
+ addiu $sp, 8
+ jr $ra
+ nop
+
+
+.global CdReadyCallback
+.type CdReadyCallback, @function
+CdReadyCallback:
+
+ addiu $sp, -12
+ sw $ra, 0($sp)
+ sw $a0, 4($sp)
+
+ la $v1, _cd_callback_int1_data
+ lw $v0, 0($v1)
+
+ la $v1, _cd_callback_int1_data
+ sw $v0, 8($sp)
+
+ jal EnterCriticalSection
+ nop
+
+ lw $a0, 4($sp)
+ nop
+ sw $a0, 0($v1)
+
+ jal ExitCriticalSection
+ nop
+
+ lw $ra, 0($sp)
+ lw $v0, 8($sp)
+ jr $ra
+ addiu $sp, 12
+
+
+.global CdSyncCallback
+.type CdSyncCallback, @function
+CdSyncCallback:
+ addiu $sp, -12
+ sw $ra, 0($sp)
+ sw $a0, 4($sp)
+
+ la $v1, _cd_sync_cb
+ lw $v0, 0($v1)
+
+ la $v1, _cd_sync_cb
+ sw $v0, 8($sp)
+
+ jal EnterCriticalSection
+ nop
+
+ lw $a0, 4($sp)
+ nop
+ sw $a0, 0($v1)
+
+ jal ExitCriticalSection
+ nop
+
+ lw $ra, 0($sp)
+ lw $v0, 8($sp)
+ jr $ra
+ addiu $sp, 12
+
+
+.section .data
+
+.global psxcd_credits
+.type psxcd_credits, @object
+psxgpu_credits:
+ .ascii "psxcd library programs by Lameguy64\n"
+ .asciiz "2019 PSn00bSDK Project / Meido-Tek Productions\n"
+
+_cd_init_msg:
+.asciiz "psxcd: Init OK\n"
+.align 4
+
+.comm _cd_last_cmd, 1, 1
+.comm _cd_last_mode, 1, 1
+.comm _cd_ack_wait, 1, 1
+.comm _cd_complt_wait, 1, 1
+
+.comm _cd_status, 1, 1
+.comm _cd_last_int, 1, 1
+
+.comm _cd_media_changed, 1, 1
+
+# Callback hooks
+.comm _cd_callback_int1_data, 4, 4 # Data IRQ callback
+.comm _cd_callback_int4, 4, 4 # Autopause callback
+.comm _cd_sync_cb, 4, 4