mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-02-27 16:15:39 +00:00
DMA: Fix DICR write breaking FMVs in FF7
This commit is contained in:
parent
9d5f3c1306
commit
6b4298541c
|
@ -30,7 +30,6 @@ bool DMA::Initialize(System* system, Bus* bus, InterruptController* interrupt_co
|
||||||
|
|
||||||
void DMA::Reset()
|
void DMA::Reset()
|
||||||
{
|
{
|
||||||
m_transfer_ticks = 0;
|
|
||||||
m_transfer_in_progress = false;
|
m_transfer_in_progress = false;
|
||||||
m_state = {};
|
m_state = {};
|
||||||
m_DPCR.bits = 0x07654321;
|
m_DPCR.bits = 0x07654321;
|
||||||
|
@ -61,11 +60,20 @@ u32 DMA::ReadRegister(u32 offset)
|
||||||
switch (offset & UINT32_C(0x0F))
|
switch (offset & UINT32_C(0x0F))
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
|
{
|
||||||
|
Log_TracePrintf("DMA%u base address -> 0x%08X", channel_index, m_state[channel_index].base_address);
|
||||||
return m_state[channel_index].base_address;
|
return m_state[channel_index].base_address;
|
||||||
|
}
|
||||||
case 0x04:
|
case 0x04:
|
||||||
|
{
|
||||||
|
Log_TracePrintf("DMA%u block control -> 0x%08X", channel_index, m_state[channel_index].block_control.bits);
|
||||||
return m_state[channel_index].block_control.bits;
|
return m_state[channel_index].block_control.bits;
|
||||||
|
}
|
||||||
case 0x08:
|
case 0x08:
|
||||||
|
{
|
||||||
|
Log_TracePrintf("DMA%u channel control -> 0x%08X", channel_index, m_state[channel_index].channel_control.bits);
|
||||||
return m_state[channel_index].channel_control.bits;
|
return m_state[channel_index].channel_control.bits;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -73,9 +81,15 @@ u32 DMA::ReadRegister(u32 offset)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (offset == 0x70)
|
if (offset == 0x70)
|
||||||
|
{
|
||||||
|
Log_TracePrintf("DPCR -> 0x%08X", m_DPCR.bits);
|
||||||
return m_DPCR.bits;
|
return m_DPCR.bits;
|
||||||
|
}
|
||||||
else if (offset == 0x74)
|
else if (offset == 0x74)
|
||||||
|
{
|
||||||
|
Log_TracePrintf("DPCR -> 0x%08X", m_DPCR.bits);
|
||||||
return m_DICR.bits;
|
return m_DICR.bits;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log_ErrorPrintf("Unhandled register read: %02X", offset);
|
Log_ErrorPrintf("Unhandled register read: %02X", offset);
|
||||||
|
@ -133,7 +147,7 @@ void DMA::WriteRegister(u32 offset, u32 value)
|
||||||
{
|
{
|
||||||
Log_TracePrintf("DCIR <- 0x%08X", value);
|
Log_TracePrintf("DCIR <- 0x%08X", value);
|
||||||
m_DICR.bits = (m_DICR.bits & ~DICR_WRITE_MASK) | (value & DICR_WRITE_MASK);
|
m_DICR.bits = (m_DICR.bits & ~DICR_WRITE_MASK) | (value & DICR_WRITE_MASK);
|
||||||
m_DICR.bits = (m_DICR.bits & ~DICR_RESET_MASK) & (value ^ DICR_RESET_MASK);
|
m_DICR.bits = m_DICR.bits & ~(value & DICR_RESET_MASK);
|
||||||
m_DICR.UpdateMasterFlag();
|
m_DICR.UpdateMasterFlag();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -186,6 +200,16 @@ bool DMA::CanRunAnyChannels() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DMA::UpdateIRQ()
|
||||||
|
{
|
||||||
|
m_DICR.UpdateMasterFlag();
|
||||||
|
if (m_DICR.master_flag)
|
||||||
|
{
|
||||||
|
Log_TracePrintf("Firing DMA master interrupt");
|
||||||
|
m_interrupt_controller->InterruptRequest(InterruptController::IRQ::DMA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DMA::Transfer()
|
void DMA::Transfer()
|
||||||
{
|
{
|
||||||
if (m_transfer_in_progress)
|
if (m_transfer_in_progress)
|
||||||
|
@ -276,8 +300,9 @@ void DMA::TransferChannel(Channel channel)
|
||||||
|
|
||||||
case SyncMode::Request:
|
case SyncMode::Request:
|
||||||
{
|
{
|
||||||
Log_DebugPrintf("DMA%u: Copying %u blocks of size %u %s 0x%08X", static_cast<u32>(channel),
|
Log_DebugPrintf("DMA%u: Copying %u blocks of size %u (%u total words) %s 0x%08X", static_cast<u32>(channel),
|
||||||
cs.block_control.request.GetBlockCount(), cs.block_control.request.GetBlockSize(),
|
cs.block_control.request.GetBlockCount(), cs.block_control.request.GetBlockSize(),
|
||||||
|
cs.block_control.request.GetBlockCount() * cs.block_control.request.GetBlockSize(),
|
||||||
copy_to_device ? "from" : "to", current_address);
|
copy_to_device ? "from" : "to", current_address);
|
||||||
|
|
||||||
const u32 block_size = cs.block_control.request.GetBlockSize();
|
const u32 block_size = cs.block_control.request.GetBlockSize();
|
||||||
|
@ -320,14 +345,9 @@ void DMA::TransferChannel(Channel channel)
|
||||||
cs.channel_control.enable_busy = false;
|
cs.channel_control.enable_busy = false;
|
||||||
if (m_DICR.IsIRQEnabled(channel))
|
if (m_DICR.IsIRQEnabled(channel))
|
||||||
{
|
{
|
||||||
Log_TracePrintf("Set DMA interrupt for channel %u", static_cast<u32>(channel));
|
Log_DebugPrintf("Set DMA interrupt for channel %u", static_cast<u32>(channel));
|
||||||
m_DICR.SetIRQFlag(channel);
|
m_DICR.SetIRQFlag(channel);
|
||||||
m_DICR.UpdateMasterFlag();
|
UpdateIRQ();
|
||||||
if (m_DICR.master_flag)
|
|
||||||
{
|
|
||||||
Log_TracePrintf("Firing DMA interrupt");
|
|
||||||
m_interrupt_controller->InterruptRequest(InterruptController::IRQ::DMA);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ private:
|
||||||
// is everything enabled for a channel to operate?
|
// is everything enabled for a channel to operate?
|
||||||
bool CanTransferChannel(Channel channel) const;
|
bool CanTransferChannel(Channel channel) const;
|
||||||
bool CanRunAnyChannels() const;
|
bool CanRunAnyChannels() const;
|
||||||
|
void UpdateIRQ();
|
||||||
|
|
||||||
void Transfer();
|
void Transfer();
|
||||||
void TransferChannel(Channel channel);
|
void TransferChannel(Channel channel);
|
||||||
|
@ -78,10 +79,8 @@ private:
|
||||||
SPU* m_spu = nullptr;
|
SPU* m_spu = nullptr;
|
||||||
MDEC* m_mdec = nullptr;
|
MDEC* m_mdec = nullptr;
|
||||||
|
|
||||||
TickCount m_transfer_ticks = 0;
|
|
||||||
bool m_transfer_in_progress = false;
|
|
||||||
|
|
||||||
std::vector<u32> m_transfer_buffer;
|
std::vector<u32> m_transfer_buffer;
|
||||||
|
bool m_transfer_in_progress = false;
|
||||||
|
|
||||||
struct ChannelState
|
struct ChannelState
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue