NES: Improve CPU OUT pins emulation

OUT pins are only updated on the GET->PUT cycle transition
This commit is contained in:
Sour 2024-09-26 21:19:10 +09:00
parent b627b25fc9
commit 6a16f729a3
3 changed files with 25 additions and 3 deletions

View file

@ -64,6 +64,9 @@ void NesConsole::ProcessCpuClock()
{
_mapper->ProcessCpuClock();
_apu->ProcessCpuClock();
if(_controlManager->HasPendingWrites()) {
_controlManager->ProcessWrites();
}
}
NesConsole* NesConsole::GetVsMainConsole()

View file

@ -250,9 +250,19 @@ uint8_t NesControlManager::ReadRam(uint16_t addr)
void NesControlManager::WriteRam(uint16_t addr, uint8_t value)
{
for(shared_ptr<BaseControlDevice> &device : _controlDevices) {
if(device->IsConnected()) {
device->WriteRam(addr, value);
//The OUT pins are only updated at the start of PUT cycles
_writeAddr = addr;
_writeValue = value;
_writePending = (_console->GetMasterClock() & 0x01) ? 1 : 2;
}
void NesControlManager::ProcessWrites()
{
if(_writePending && --_writePending == 0) {
for(shared_ptr<BaseControlDevice>& device : _controlDevices) {
if(device->IsConnected()) {
device->WriteRam(_writeAddr, _writeValue);
}
}
}
}
@ -266,6 +276,9 @@ void NesControlManager::Serialize(Serializer& s)
{
BaseControlManager::Serialize(s);
SV(_lagCounter);
SV(_writeAddr);
SV(_writeValue);
SV(_writePending);
if(!s.IsSaving()) {
UpdateControlDevices();

View file

@ -19,6 +19,9 @@ class NesControlManager : public INesMemoryHandler, public BaseControlManager
{
private:
NesConfig _prevConfig = {};
uint16_t _writeAddr = 0;
uint8_t _writeValue = 0;
uint8_t _writePending = 0;
protected:
NesConsole* _console;
@ -51,4 +54,7 @@ public:
uint8_t ReadRam(uint16_t addr) override;
void WriteRam(uint16_t addr, uint8_t value) override;
__noinline void ProcessWrites();
__forceinline bool HasPendingWrites() { return _writePending > 0; }
};