Refactor timing to allow sync/updates in the middle of a slice
This commit is contained in:
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user