mirror of
https://github.com/HackerN64/F3DEX3.git
synced 2026-01-21 10:37:45 -08:00
57 lines
3.7 KiB
ArmAsm
57 lines
3.7 KiB
ArmAsm
|
|
flush_rdp_buffer: // Prereq: dmemAddr = rdpCmdBufPtr - rdpCmdBufEndP1, or dmemAddr = large neg num -> only wait and set DPC_END
|
||
|
|
mfc0 $11, SP_DMA_BUSY // Check if any DMA is in flight
|
||
|
|
lw cmd_w1_dram, rdpFifoPos // FIFO pointer = end of RDP read, start of RSP write
|
||
|
|
lw $10, OSTask + OSTask_output_buff_size // Load FIFO "size" (actually end addr)
|
||
|
|
.if CFG_PROFILING_C
|
||
|
|
// This is a wait for DMA busy loop, but written inline to avoid overwriting ra.
|
||
|
|
addi perfCounterD, perfCounterD, 7 // 6 instr + 1 taken branch
|
||
|
|
.endif
|
||
|
|
bnez $11, flush_rdp_buffer // Wait until no DMAs are active
|
||
|
|
addi dmaLen, dmemAddr, RDP_CMD_BUFSIZE + 8 // dmaLen = size of DMEM buffer to copy
|
||
|
|
blez dmaLen, old_return_routine // Exit if nothing to copy, or if dmemAddr is large negative num from last flush DMA write
|
||
|
|
mtc0 cmd_w1_dram, DPC_END // Set RDP to execute until FIFO end (buf pushed last time)
|
||
|
|
add $11, cmd_w1_dram, dmaLen // $11 = future FIFO pointer if we append this new buffer
|
||
|
|
sub $10, $10, $11 // $10 = FIFO end addr - future pointer
|
||
|
|
bgez $10, @@has_room // Branch if we can fit this
|
||
|
|
@@await_rdp_dblbuf_avail:
|
||
|
|
mfc0 $11, DPC_STATUS // Read RDP status
|
||
|
|
andi $11, $11, DPC_STATUS_START_VALID // Start valid = second start addr in dbl buf
|
||
|
|
bnez $11, @@await_rdp_dblbuf_avail // Wait until double buffered start/end available
|
||
|
|
.if COUNTER_C_FIFO_FULL
|
||
|
|
addi perfCounterC, perfCounterC, 7 // 4 instr + 2 after mfc + 1 taken branch
|
||
|
|
.endif
|
||
|
|
lw cmd_w1_dram, OSTask + OSTask_output_buff // Start of FIFO
|
||
|
|
@@await_past_first_instr:
|
||
|
|
mfc0 $11, DPC_CURRENT // Load RDP current pointer
|
||
|
|
beq $11, cmd_w1_dram, @@await_past_first_instr // Wait until RDP moved past start
|
||
|
|
.if COUNTER_C_FIFO_FULL
|
||
|
|
addi perfCounterC, perfCounterC, 6 // 3 instr + 2 after mfc + 1 taken branch
|
||
|
|
.else
|
||
|
|
nop
|
||
|
|
.endif
|
||
|
|
// Start was previously the start of the FIFO, unless this is the first buffer,
|
||
|
|
// in which case it was the end of the FIFO. Normally, when the RDP gets to end, if we
|
||
|
|
// have a new end value waiting (END_VALID), it'll load end but leave current. By
|
||
|
|
// setting start here, it will also load current with start.
|
||
|
|
mtc0 cmd_w1_dram, DPC_START // Set RDP start to start of FIFO
|
||
|
|
@@keep_waiting:
|
||
|
|
.if COUNTER_C_FIFO_FULL
|
||
|
|
// This is here so we only count it when stalling below or on FIFO end codepath
|
||
|
|
addi perfCounterC, perfCounterC, 10 // 7 instr + 2 after mfc + 1 taken branch
|
||
|
|
.endif
|
||
|
|
@@has_room:
|
||
|
|
mfc0 $11, DPC_CURRENT // Load RDP current pointer
|
||
|
|
sub $11, $11, cmd_w1_dram // Current - current end (rdpFifoPos or start)
|
||
|
|
blez $11, @@copy_buffer // Current is behind or at current end, can do copy
|
||
|
|
sub $11, $11, dmaLen // If amount current is ahead of current end
|
||
|
|
blez $11, @@keep_waiting // is <= size of buffer to copy, keep waiting
|
||
|
|
@@copy_buffer:
|
||
|
|
add $11, cmd_w1_dram, dmaLen // New end is current end + buffer size
|
||
|
|
sw $11, rdpFifoPos
|
||
|
|
// Set up the DMA from DMEM to the RDP fifo in RDRAM
|
||
|
|
addi dmaLen, dmaLen, -1 // subtract 1 from the length
|
||
|
|
addi dmemAddr, rdpCmdBufEndP1, -(0x2000 | (RDP_CMD_BUFSIZE + 8)) // The 0x2000 is meaningless, negative means write
|
||
|
|
xori rdpCmdBufEndP1, rdpCmdBufEndP1, rdpCmdBuffer1EndPlus1Word ^ rdpCmdBuffer2EndPlus1Word // Swap between the two RDP command buffers
|
||
|
|
j dma_read_write
|
||
|
|
addi rdpCmdBufPtr, rdpCmdBufEndP1, -(RDP_CMD_BUFSIZE + 8)
|