mirror of
https://github.com/SourMesen/Mesen2.git
synced 2025-04-02 10:21:44 -04:00
98 lines
2.4 KiB
C++
98 lines
2.4 KiB
C++
#include "pch.h"
|
|
#include "WS/WsTimer.h"
|
|
#include "WS/WsMemoryManager.h"
|
|
#include "Utilities/BitUtilities.h"
|
|
|
|
void WsTimer::Init(WsMemoryManager* memoryManager)
|
|
{
|
|
_memoryManager = memoryManager;
|
|
}
|
|
|
|
void WsTimer::TickHorizontalTimer()
|
|
{
|
|
if(_state.HTimer == 1) {
|
|
_memoryManager->SetIrqSource(WsIrqSource::HorizontalBlankTimer);
|
|
}
|
|
|
|
if(_state.HBlankEnabled) {
|
|
if(_state.HTimer && !--_state.HTimer && _state.HBlankAutoReload) {
|
|
_state.HTimer = _state.HReloadValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
void WsTimer::TickVerticalTimer()
|
|
{
|
|
if(_state.VTimer == 1) {
|
|
_memoryManager->SetIrqSource(WsIrqSource::VerticalBlankTimer);
|
|
}
|
|
|
|
if(_state.VBlankEnabled) {
|
|
if(_state.VTimer && !--_state.VTimer && _state.VBlankAutoReload) {
|
|
_state.VTimer = _state.VReloadValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint8_t WsTimer::ReadPort(uint16_t port)
|
|
{
|
|
switch(port) {
|
|
case 0xA2: return _state.Control;
|
|
case 0xA4: return BitUtilities::GetBits<0>(_state.HReloadValue); break;
|
|
case 0xA5: return BitUtilities::GetBits<8>(_state.HReloadValue); break;
|
|
case 0xA6: return BitUtilities::GetBits<0>(_state.VReloadValue); break;
|
|
case 0xA7: return BitUtilities::GetBits<8>(_state.VReloadValue); break;
|
|
case 0xA8: return BitUtilities::GetBits<0>(_state.HTimer); break;
|
|
case 0xA9: return BitUtilities::GetBits<8>(_state.HTimer); break;
|
|
case 0xAA: return BitUtilities::GetBits<0>(_state.VTimer); break;
|
|
case 0xAB: return BitUtilities::GetBits<8>(_state.VTimer); break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void WsTimer::WritePort(uint16_t port, uint8_t value)
|
|
{
|
|
switch(port) {
|
|
case 0xA2:
|
|
_state.Control = value & 0x0F;
|
|
_state.HBlankEnabled = value & 0x01;
|
|
_state.HBlankAutoReload = value & 0x02;
|
|
_state.VBlankEnabled = value & 0x04;
|
|
_state.VBlankAutoReload = value & 0x08;
|
|
break;
|
|
|
|
case 0xA4:
|
|
BitUtilities::SetBits<0>(_state.HReloadValue, value);
|
|
_state.HTimer = _state.HReloadValue;
|
|
break;
|
|
|
|
case 0xA5:
|
|
BitUtilities::SetBits<8>(_state.HReloadValue, value);
|
|
_state.HTimer = _state.HReloadValue;
|
|
break;
|
|
|
|
case 0xA6:
|
|
BitUtilities::SetBits<0>(_state.VReloadValue, value);
|
|
_state.VTimer = _state.VReloadValue;
|
|
break;
|
|
|
|
case 0xA7:
|
|
BitUtilities::SetBits<8>(_state.VReloadValue, value);
|
|
_state.VTimer = _state.VReloadValue;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void WsTimer::Serialize(Serializer& s)
|
|
{
|
|
SV(_state.HTimer);
|
|
SV(_state.VTimer);
|
|
SV(_state.HReloadValue);
|
|
SV(_state.VReloadValue);
|
|
SV(_state.Control);
|
|
SV(_state.HBlankEnabled);
|
|
SV(_state.HBlankAutoReload);
|
|
SV(_state.VBlankEnabled);
|
|
SV(_state.VBlankAutoReload);
|
|
}
|