DMA: Fix range check in mode0 when decrementing

Fixes lag on startup in Clone (Euro Demo 42).
This commit is contained in:
Stenzek 2024-05-31 22:29:32 +10:00
parent c637e2b337
commit 3e3572c410
No known key found for this signature in database

View file

@ -574,7 +574,7 @@ bool DMA::TransferChannel()
current_address); current_address);
const PhysicalMemoryAddress transfer_addr = current_address & TRANSFER_ADDRESS_MASK; const PhysicalMemoryAddress transfer_addr = current_address & TRANSFER_ADDRESS_MASK;
if (CheckForBusError(channel, cs, transfer_addr, word_count * sizeof(u32))) [[unlikely]] if (CheckForBusError(channel, cs, transfer_addr, (word_count - 1) * increment)) [[unlikely]]
return true; return true;
TickCount used_ticks; TickCount used_ticks;
@ -608,7 +608,7 @@ bool DMA::TransferChannel()
{ {
u32 header; u32 header;
PhysicalMemoryAddress transfer_addr = current_address & TRANSFER_ADDRESS_MASK; PhysicalMemoryAddress transfer_addr = current_address & TRANSFER_ADDRESS_MASK;
if (CheckForBusError(channel, cs, current_address, sizeof(header))) [[unlikely]] if (CheckForBusError(channel, cs, transfer_addr, sizeof(header))) [[unlikely]]
{ {
cs.base_address = current_address; cs.base_address = current_address;
return true; return true;
@ -628,6 +628,12 @@ bool DMA::TransferChannel()
if (word_count > 0) if (word_count > 0)
{ {
if (CheckForBusError(channel, cs, transfer_addr, (word_count - 1) * increment)) [[unlikely]]
{
cs.base_address = current_address;
return true;
}
const TickCount block_ticks = TransferMemoryToDevice<channel>(transfer_addr + sizeof(header), 4, word_count); const TickCount block_ticks = TransferMemoryToDevice<channel>(transfer_addr + sizeof(header), 4, word_count);
CPU::AddPendingTicks(block_ticks); CPU::AddPendingTicks(block_ticks);
remaining_ticks -= block_ticks; remaining_ticks -= block_ticks;
@ -673,7 +679,7 @@ bool DMA::TransferChannel()
do do
{ {
const PhysicalMemoryAddress transfer_addr = current_address & TRANSFER_ADDRESS_MASK; const PhysicalMemoryAddress transfer_addr = current_address & TRANSFER_ADDRESS_MASK;
if (CheckForBusError(channel, cs, transfer_addr, block_size * increment)) [[unlikely]] if (CheckForBusError(channel, cs, transfer_addr, (block_size - 1) * increment)) [[unlikely]]
{ {
cs.base_address = current_address; cs.base_address = current_address;
cs.block_control.request.block_count = blocks_remaining; cs.block_control.request.block_count = blocks_remaining;
@ -694,7 +700,7 @@ bool DMA::TransferChannel()
do do
{ {
const PhysicalMemoryAddress transfer_addr = current_address & TRANSFER_ADDRESS_MASK; const PhysicalMemoryAddress transfer_addr = current_address & TRANSFER_ADDRESS_MASK;
if (CheckForBusError(channel, cs, transfer_addr, block_size * increment)) [[unlikely]] if (CheckForBusError(channel, cs, transfer_addr, (block_size - 1) * increment)) [[unlikely]]
{ {
cs.base_address = current_address; cs.base_address = current_address;
cs.block_control.request.block_count = blocks_remaining; cs.block_control.request.block_count = blocks_remaining;