Skip to content

Commit 5986b3b

Browse files
committed
Implement missing RSP DMA features
1 parent 913939d commit 5986b3b

File tree

1 file changed

+34
-28
lines changed

1 file changed

+34
-28
lines changed

src/rsp_cp0.cpp

+34-28
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ namespace RSP_CP0
3131
uint32_t status;
3232
uint32_t semaphore;
3333

34-
void performReadDma(uint32_t address);
35-
void performWriteDma(uint32_t address);
34+
void performReadDma(uint32_t length, uint32_t count, uint32_t skip);
35+
void performWriteDma(uint32_t length, uint32_t count, uint32_t skip);
3636
}
3737

3838
void RSP_CP0::reset()
@@ -79,30 +79,22 @@ void RSP_CP0::write(int index, uint32_t value)
7979
{
8080
case 0: // SP_MEM_ADDR
8181
// Set the RSP DMA address
82-
memAddr = value & 0x1FFF;
82+
memAddr = value & 0x1FF8;
8383
return;
8484

8585
case 1: // SP_DRAM_ADDR
8686
// Set the RDRAM DMA address
87-
dramAddr = value & 0xFFFFFF;
87+
dramAddr = value & 0xFFFFF8;
8888
return;
8989

9090
case 2: // SP_RD_LEN
9191
// Start a DMA transfer from RDRAM to RSP MEM
92-
performReadDma((value & 0xFF8) + 1);
93-
94-
// Keep track of unimplemented bits that should do something
95-
if (uint32_t bits = (value & 0xFF8FF000))
96-
LOG_WARN("Unimplemented RSP CP0 read length bits set: 0x%X\n", bits);
92+
performReadDma(value & 0xFF8, (value >> 12) & 0xFF, (value >> 20) & 0xFF8);
9793
return;
9894

9995
case 3: // SP_WR_LEN
10096
// Start a DMA transfer from RSP MEM to RDRAM
101-
performWriteDma((value & 0xFF8) + 1);
102-
103-
// Keep track of unimplemented bits that should do something
104-
if (uint32_t bits = (value & 0xFF8FF000))
105-
LOG_WARN("Unimplemented RSP CP0 write length bits set: 0x%X\n", bits);
97+
performWriteDma(value & 0xFF8, (value >> 12) & 0xFF, (value >> 20) & 0xFF8);
10698
return;
10799

108100
case 4: // SP_STATUS
@@ -162,28 +154,42 @@ void RSP_CP0::triggerBreak()
162154
status |= 0x3;
163155
}
164156

165-
void RSP_CP0::performReadDma(uint32_t size)
157+
void RSP_CP0::performReadDma(uint32_t length, uint32_t count, uint32_t skip)
166158
{
167-
LOG_INFO("RSP DMA from RDRAM 0x%X to RSP MEM 0x%X with size 0x%X\n", dramAddr, memAddr, size);
159+
LOG_INFO("RSP DMA from RDRAM 0x%X to RSP MEM 0x%X with length 0x%X, "
160+
"count 0x%X, skip 0x%X\n", dramAddr, memAddr, length, count, skip);
168161

169-
// Copy data from memory to the RSP
170-
for (uint32_t i = 0; i < size; i += 8)
162+
// Copy rows of data from memory to the RSP
163+
uint32_t dramBase = dramAddr, memBase = memAddr;
164+
for (uint32_t c = 0; c <= count; c++)
171165
{
172-
uint32_t dst = 0x84000000 + ((memAddr + i) & 0x1FFF);
173-
uint32_t src = 0x80000000 + dramAddr + i;
174-
Memory::write<uint64_t>(dst & ~7, Memory::read<uint64_t>(src & ~7));
166+
for (uint32_t l = 0; l <= length; l += 8)
167+
{
168+
uint32_t dst = 0x84000000 + ((memBase + l) & 0x1FF8);
169+
uint32_t src = 0x80000000 + ((dramBase + l) & 0xFFFFF8);
170+
Memory::write<uint64_t>(dst, Memory::read<uint64_t>(src));
171+
}
172+
dramBase += length + skip + 8;
173+
memBase += length + 8;
175174
}
176175
}
177176

178-
void RSP_CP0::performWriteDma(uint32_t size)
177+
void RSP_CP0::performWriteDma(uint32_t length, uint32_t count, uint32_t skip)
179178
{
180-
LOG_INFO("RSP DMA from RSP MEM 0x%X to RDRAM 0x%X with size 0x%X\n", memAddr, dramAddr, size);
179+
LOG_INFO("RSP DMA from RSP MEM 0x%X to RDRAM 0x%X with length 0x%X, "
180+
"count 0x%X, skip 0x%X\n", memAddr, dramAddr, length, count, skip);
181181

182-
// Copy data from the RSP to memory
183-
for (uint32_t i = 0; i < size; i += 8)
182+
// Copy rows of data from the RSP to memory
183+
uint32_t dramBase = dramAddr, memBase = memAddr;
184+
for (uint32_t c = 0; c <= count; c++)
184185
{
185-
uint32_t dst = 0x80000000 + dramAddr + i;
186-
uint32_t src = 0x84000000 + ((memAddr + i) & 0x1FFF);
187-
Memory::write<uint64_t>(dst & ~7, Memory::read<uint64_t>(src & ~7));
186+
for (uint32_t l = 0; l <= length; l += 8)
187+
{
188+
uint32_t dst = 0x80000000 + ((dramBase + l) & 0xFFFFF8);
189+
uint32_t src = 0x84000000 + ((memBase + l) & 0x1FF8);
190+
Memory::write<uint64_t>(dst, Memory::read<uint64_t>(src));
191+
}
192+
dramBase += length + skip + 8;
193+
memBase += length + 8;
188194
}
189195
}

0 commit comments

Comments
 (0)