Mesen2/Core/WS/WsCpuPrefetch.cpp
2024-09-19 21:19:43 +09:00

93 lines
1.5 KiB
C++

#include "pch.h"
#include "WS/WsCpuPrefetch.h"
#include "WS/WsMemoryManager.h"
#include "WS/WsCpu.h"
WsCpuPrefetch::WsCpuPrefetch(WsCpu* cpu, WsMemoryManager* memoryManager)
{
_cpu = cpu;
_memoryManager = memoryManager;
}
bool WsCpuPrefetch::IsFull()
{
return _size >= 16;
}
void WsCpuPrefetch::PushByte(uint8_t value)
{
_data[(_writePos++) & 0x0F] = value;
_fetchIp++;
_size++;
}
void WsCpuPrefetch::Prefetch()
{
_cpu->ProcessCpuCycle();
_waitCycles++;
if(IsFull()) {
return;
}
uint32_t addr = ((_fetchCs << 4) + _fetchIp) & 0xFFFFF;
uint8_t cycles = _memoryManager->GetWaitStates(addr);
if(_waitCycles < cycles) {
return;
}
_waitCycles = 0;
bool isWordBus = _memoryManager->IsWordBus(addr);
//TODOWS debugger can't see these reads
PushByte(_memoryManager->InternalRead(addr));
if(!IsFull() && isWordBus && (_fetchIp & 0x01)) {
PushByte(_memoryManager->InternalRead(((_fetchCs << 4) + _fetchIp)) & 0xFFFFF);
}
}
void WsCpuPrefetch::ProcessRep(uint8_t opCode)
{
if(IsFull()) {
_writePos--;
_fetchIp--;
_size--;
}
_readPos--;
_size++;
_data[_readPos & 0x0F] = opCode;
}
uint8_t WsCpuPrefetch::Read()
{
while(_size < 2) {
Prefetch();
}
_size--;
return _data[(_readPos++) & 0x0F];
}
void WsCpuPrefetch::Clear(uint16_t cs, uint16_t ip)
{
_fetchCs = cs;
_fetchIp = ip;
_size = 0;
_readPos = 0;
_writePos = 0;
_waitCycles = 0;
}
void WsCpuPrefetch::Serialize(Serializer& s)
{
SV(_fetchCs);
SV(_fetchIp);
SV(_readPos);
SV(_writePos);
SV(_size);
SV(_waitCycles);
SVArray(_data, 16);
}