Refactor timing to allow sync/updates in the middle of a slice

This commit is contained in:
Connor McLaughlin
2019-09-20 23:59:48 +10:00
parent ad316162f3
commit c988af453c
10 changed files with 74 additions and 36 deletions

View File

@ -2,14 +2,16 @@
#include "YBaseLib/Log.h"
#include "common/state_wrapper.h"
#include "interrupt_controller.h"
#include "system.h"
Log_SetChannel(Timers);
Timers::Timers() = default;
Timers::~Timers() = default;
bool Timers::Initialize(InterruptController* interrupt_controller)
bool Timers::Initialize(System* system, InterruptController* interrupt_controller)
{
m_system = system;
m_interrupt_controller = interrupt_controller;
return true;
}
@ -103,6 +105,16 @@ void Timers::AddTicks(u32 timer, u32 count)
cs.counter = 0;
}
void Timers::AddSystemTicks(u32 ticks)
{
if (!m_states[0].external_counting_enabled && m_states[0].counting_enabled)
AddTicks(0, ticks);
if (!m_states[1].external_counting_enabled && m_states[1].counting_enabled)
AddTicks(1, ticks);
if (m_states[2].counting_enabled)
AddTicks(2, m_states[2].external_counting_enabled ? (ticks / 8) : (ticks));
}
u32 Timers::ReadRegister(u32 offset)
{
const u32 timer_index = (offset >> 4) & u32(0x03);
@ -113,15 +125,20 @@ u32 Timers::ReadRegister(u32 offset)
switch (port_offset)
{
case 0x00:
{
m_system->Synchronize();
return cs.counter;
}
case 0x04:
{
m_system->Synchronize();
const u32 bits = cs.mode.bits;
cs.mode.reached_overflow = false;
cs.mode.reached_target = false;
return bits;
}
break;
case 0x08:
return cs.target;
@ -142,13 +159,17 @@ void Timers::WriteRegister(u32 offset, u32 value)
switch (port_offset)
{
case 0x00:
{
Log_DebugPrintf("Timer %u write counter %u", timer_index, value);
m_system->Synchronize();
cs.counter = value & u32(0xFFFF);
break;
}
break;
case 0x04:
{
Log_DebugPrintf("Timer %u write mode register 0x%04X", timer_index, value);
m_system->Synchronize();
cs.mode.bits = value & u32(0x1FFF);
cs.use_external_clock = (cs.mode.clock_source & (timer_index == 2 ? 2 : 1)) != 0;
cs.counter = 0;
@ -157,9 +178,12 @@ void Timers::WriteRegister(u32 offset, u32 value)
break;
case 0x08:
{
Log_DebugPrintf("Timer %u write target 0x%04X", timer_index, ZeroExtend32(Truncate16(value)));
m_system->Synchronize();
cs.target = value & u32(0xFFFF);
break;
}
break;
default:
Log_ErrorPrintf("Write unknown register in timer %u (offset 0x%02X, value 0x%X)", offset, value);