Implement gate edge reset in EE timers.

This commit is contained in:
Jean-Philip Desjardins 2017-02-23 09:49:56 -05:00
parent f4c4ca2c05
commit 5016189b87
3 changed files with 52 additions and 4 deletions

View File

@ -333,6 +333,7 @@ void CSubSystem::CountTicks(int ticks)
void CSubSystem::NotifyVBlankStart()
{
m_timer.NotifyVBlankStart();
m_intc.AssertLine(CINTC::INTC_LINE_VBLANK_START);
if(m_os->CheckVBlankFlag())
{
@ -344,6 +345,7 @@ void CSubSystem::NotifyVBlankStart()
void CSubSystem::NotifyVBlankEnd()
{
m_timer.NotifyVBlankEnd();
m_intc.AssertLine(CINTC::INTC_LINE_VBLANK_END);
}

View File

@ -263,3 +263,32 @@ void CTimer::SaveState(Framework::CZipArchiveWriter& archive)
}
archive.InsertFile(registerFile);
}
void CTimer::NotifyVBlankStart()
{
ProcessGateEdgeChange(MODE_GATE_SELECT_VBLANK, MODE_GATE_MODE_HIGHEDGE);
}
void CTimer::NotifyVBlankEnd()
{
ProcessGateEdgeChange(MODE_GATE_SELECT_VBLANK, MODE_GATE_MODE_LOWEDGE);
}
void CTimer::ProcessGateEdgeChange(uint32 gate, uint32 edgeMode)
{
for(unsigned int i = 0; i < MAX_TIMER; i++)
{
auto& timer = m_timer[i];
if(!(timer.nMODE & MODE_COUNT_ENABLE)) continue;
if(!(timer.nMODE & MODE_GATE_ENABLE)) continue;
if((timer.nMODE & MODE_GATE_SELECT) != gate) continue;
uint32 gateMode = (timer.nMODE & MODE_GATE_MODE);
if((edgeMode & gateMode) == edgeMode)
{
timer.nCOUNT = 0;
timer.clockRemain = 0;
}
}
}

View File

@ -10,10 +10,22 @@ class CTimer
public:
enum
{
MODE_ZERO_RETURN = 0x040,
MODE_COUNT_ENABLE = 0x080,
MODE_EQUAL_FLAG = 0x400,
MODE_OVERFLOW_FLAG = 0x800,
MODE_GATE_ENABLE = 0x004,
MODE_GATE_SELECT = 0x008,
MODE_GATE_SELECT_HBLANK = 0x000,
MODE_GATE_SELECT_VBLANK = 0x008,
MODE_GATE_MODE = 0x030,
MODE_GATE_MODE_COUNTLOW = 0x000,
MODE_GATE_MODE_HIGHEDGE = 0x010,
MODE_GATE_MODE_LOWEDGE = 0x020,
MODE_GATE_MODE_BOTHEDGE = 0x030,
MODE_ZERO_RETURN = 0x040,
MODE_COUNT_ENABLE = 0x080,
MODE_EQUAL_FLAG = 0x400,
MODE_OVERFLOW_FLAG = 0x800,
};
CTimer(CINTC&);
@ -29,6 +41,9 @@ public:
void LoadState(Framework::CZipArchiveReader&);
void SaveState(Framework::CZipArchiveWriter&);
void NotifyVBlankStart();
void NotifyVBlankEnd();
private:
enum
{
@ -38,6 +53,8 @@ private:
void DisassembleGet(uint32);
void DisassembleSet(uint32, uint32);
void ProcessGateEdgeChange(uint32, uint32);
struct TIMER
{
uint32 nCOUNT;