DMA: Remove timing events

We'll probably need to revert/re-add a variant of this when we
eventually implement chopping. But for now it simplifies things.
This commit is contained in:
Connor McLaughlin 2020-03-29 01:12:44 +10:00
parent 423f04325f
commit 5dbdc0b60c
2 changed files with 12 additions and 75 deletions

View File

@ -26,13 +26,6 @@ void DMA::Initialize(System* system, Bus* bus, InterruptController* interrupt_co
m_spu = spu; m_spu = spu;
m_mdec = mdec; m_mdec = mdec;
m_transfer_buffer.resize(32); m_transfer_buffer.resize(32);
for (u32 i = 0; i < NUM_CHANNELS; i++)
{
m_state[i].transfer_event = system->CreateTimingEvent(
StringUtil::StdStringFromFormat("DMA%u Transfer", i), 1, 1,
std::bind(&DMA::TransferChannel, this, static_cast<Channel>(i), std::placeholders::_2), false);
}
} }
void DMA::Reset() void DMA::Reset()
@ -46,7 +39,6 @@ void DMA::Reset()
cs.block_control.bits = 0; cs.block_control.bits = 0;
cs.channel_control.bits = 0; cs.channel_control.bits = 0;
cs.request = false; cs.request = false;
cs.transfer_event->Deactivate();
} }
} }
@ -64,15 +56,6 @@ bool DMA::DoState(StateWrapper& sw)
sw.Do(&m_DPCR.bits); sw.Do(&m_DPCR.bits);
sw.Do(&m_DICR.bits); sw.Do(&m_DICR.bits);
if (sw.IsReading())
{
for (u32 i = 0; i < NUM_CHANNELS; i++)
{
m_state[i].transfer_event->Deactivate();
UpdateChannelTransferEvent(static_cast<Channel>(i));
}
}
return !sw.HasError(); return !sw.HasError();
} }
@ -138,7 +121,8 @@ void DMA::WriteRegister(u32 offset, u32 value)
{ {
Log_TracePrintf("DMA channel %u block control <- 0x%08X", channel_index, value); Log_TracePrintf("DMA channel %u block control <- 0x%08X", channel_index, value);
state.block_control.bits = value; state.block_control.bits = value;
UpdateChannelTransferEvent(static_cast<Channel>(channel_index)); if (CanTransferChannel(static_cast<Channel>(channel_index)))
TransferChannel(static_cast<Channel>(channel_index));
return; return;
} }
@ -152,7 +136,8 @@ void DMA::WriteRegister(u32 offset, u32 value)
if (static_cast<Channel>(channel_index) == Channel::OTC) if (static_cast<Channel>(channel_index) == Channel::OTC)
SetRequest(static_cast<Channel>(channel_index), state.channel_control.start_trigger); SetRequest(static_cast<Channel>(channel_index), state.channel_control.start_trigger);
UpdateChannelTransferEvent(static_cast<Channel>(channel_index)); if (CanTransferChannel(static_cast<Channel>(channel_index)))
TransferChannel(static_cast<Channel>(channel_index));
return; return;
} }
@ -169,7 +154,10 @@ void DMA::WriteRegister(u32 offset, u32 value)
Log_TracePrintf("DPCR <- 0x%08X", value); Log_TracePrintf("DPCR <- 0x%08X", value);
m_DPCR.bits = value; m_DPCR.bits = value;
for (u32 i = 0; i < NUM_CHANNELS; i++) for (u32 i = 0; i < NUM_CHANNELS; i++)
UpdateChannelTransferEvent(static_cast<Channel>(i)); {
if (CanTransferChannel(static_cast<Channel>(i)))
TransferChannel(static_cast<Channel>(i));
}
return; return;
} }
@ -197,18 +185,8 @@ void DMA::SetRequest(Channel channel, bool request)
return; return;
cs.request = request; cs.request = request;
if (request) if (CanTransferChannel(channel))
UpdateChannelTransferEvent(channel); TransferChannel(channel);
}
TickCount DMA::GetTransferDelay(Channel channel) const
{
const ChannelState& cs = m_state[static_cast<u32>(channel)];
switch (channel)
{
default:
return 0;
}
} }
bool DMA::CanTransferChannel(Channel channel) const bool DMA::CanTransferChannel(Channel channel) const
@ -223,17 +201,6 @@ bool DMA::CanTransferChannel(Channel channel) const
return cs.request; return cs.request;
} }
bool DMA::CanRunAnyChannels() const
{
for (u32 i = 0; i < NUM_CHANNELS; i++)
{
if (CanTransferChannel(static_cast<Channel>(i)))
return true;
}
return false;
}
void DMA::UpdateIRQ() void DMA::UpdateIRQ()
{ {
m_DICR.UpdateMasterFlag(); m_DICR.UpdateMasterFlag();
@ -244,33 +211,9 @@ void DMA::UpdateIRQ()
} }
} }
void DMA::UpdateChannelTransferEvent(Channel channel) void DMA::TransferChannel(Channel channel)
{ {
ChannelState& cs = m_state[static_cast<u32>(channel)]; ChannelState& cs = m_state[static_cast<u32>(channel)];
if (!CanTransferChannel(channel))
{
cs.transfer_event->Deactivate();
return;
}
if (cs.transfer_event->IsActive())
return;
const TickCount ticks = GetTransferDelay(channel);
if (ticks == 0)
{
// immediate transfer
TransferChannel(channel, 0);
return;
}
cs.transfer_event->SetPeriodAndSchedule(ticks);
}
void DMA::TransferChannel(Channel channel, TickCount ticks_late)
{
ChannelState& cs = m_state[static_cast<u32>(channel)];
cs.transfer_event->Deactivate();
const bool copy_to_device = cs.channel_control.copy_to_device; const bool copy_to_device = cs.channel_control.copy_to_device;

View File

@ -64,16 +64,11 @@ private:
Reserved = 3 Reserved = 3
}; };
/// Returns the number of ticks for a given channel's transfer.
TickCount GetTransferDelay(Channel channel) const;
// 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;
void UpdateIRQ(); void UpdateIRQ();
void UpdateChannelTransferEvent(Channel channel); void TransferChannel(Channel channel);
void TransferChannel(Channel channel, TickCount ticks_late);
// from device -> memory // from device -> memory
void TransferDeviceToMemory(Channel channel, u32 address, u32 increment, u32 word_count); void TransferDeviceToMemory(Channel channel, u32 address, u32 increment, u32 word_count);
@ -93,7 +88,6 @@ private:
struct ChannelState struct ChannelState
{ {
std::unique_ptr<TimingEvent> transfer_event;
u32 base_address = 0; u32 base_address = 0;
union BlockControl union BlockControl