Skip to content

Commit

Permalink
NES: Fixed EPSM issues when using "long writes"
Browse files Browse the repository at this point in the history
The OUT1 pin was using bit 1 of the data bus, which is incorrect (should match the last value writting to 4016)
  • Loading branch information
SourMesen committed Oct 15, 2024
1 parent b9d0c0b commit 6ea096b
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 11 deletions.
18 changes: 10 additions & 8 deletions Core/NES/Epsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,25 @@ Epsm::~Epsm()
_emu->GetSoundMixer()->UnregisterAudioProvider(this);
}

void Epsm::Write(uint8_t value)
void Epsm::Write(uint8_t dataBus, uint8_t outPins)
{
//4016 writes
bool isHigh = (value & 0x02);
bool wasHigh = (_prevValue & 0x02);
//The EPSM uses the value of the data bus + the OUT1 pin
//The OUT1 can be delayed by a cycle, but not the data bus
bool isHigh = (outPins & 0x02);
bool wasHigh = (_prevOutPins & 0x02);

if(isHigh && !wasHigh) {
//rising edge
_data = (value & 0xF0) | (_data & 0x0F);
_addr = ((value & 0x04) >> 1) | ((value & 0x08) >> 3);
_data = (dataBus & 0xF0) | (_data & 0x0F);
_addr = ((dataBus & 0x04) >> 1) | ((dataBus & 0x08) >> 3);
} else if(!isHigh && wasHigh) {
//falling edge
_data = (_data & 0xF0) | ((value & 0xF0) >> 4);
_data = (_data & 0xF0) | ((dataBus & 0xF0) >> 4);
_opn.Write(_addr, _data);
}

_prevValue = value;
_prevOutPins = outPins;
}

void Epsm::WriteRam(uint16_t addr, uint8_t value)
Expand Down Expand Up @@ -98,7 +100,7 @@ uint8_t Epsm::ReadRam(uint16_t addr)
void Epsm::Serialize(Serializer& s)
{
SV(_clockCounter);
SV(_prevValue);
SV(_prevOutPins);
SV(_addr);
SV(_data);
SV(_masterClockRate);
Expand Down
4 changes: 2 additions & 2 deletions Core/NES/Epsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Epsm : public IAudioProvider, public INesMemoryHandler, public ISerializab
uint64_t _masterClockRate = 0;
uint64_t _clockCounter = 0;
uint8_t _sampleClockCounter = 0;
uint8_t _prevValue = 0;
uint8_t _prevOutPins = 0;
uint8_t _data = 0;
uint8_t _addr = 0;

Expand All @@ -32,7 +32,7 @@ class Epsm : public IAudioProvider, public INesMemoryHandler, public ISerializab
Epsm(Emulator* emu, NesConsole* console, vector<uint8_t>& adpcmRom);
~Epsm();

void Write(uint8_t value);
void Write(uint8_t dataBus, uint8_t outPins);
void WriteRam(uint16_t addr, uint8_t value) override;
void Exec();

Expand Down
2 changes: 1 addition & 1 deletion Core/NES/NesControlManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ void NesControlManager::ProcessWrites()
{
if(_writePending && --_writePending == 0) {
if(_console->GetEpsm() && _writeAddr == 0x4016) {
_console->GetEpsm()->Write(_console->GetMemoryManager()->GetOpenBus());
_console->GetEpsm()->Write(_console->GetMemoryManager()->GetOpenBus(), _writeValue);
}

for(shared_ptr<BaseControlDevice>& device : _controlDevices) {
Expand Down

0 comments on commit 6ea096b

Please sign in to comment.