mirror of
https://github.com/libretro/Mesen.git
synced 2024-11-27 02:50:28 +00:00
DMC: Fixed DMC DMA timing & $4011 write behavior.
Fixes dmc_pitch without breaking sprdma_and_dmc_dma tests.
This commit is contained in:
parent
d0cc79aeed
commit
f540fc766d
@ -131,7 +131,7 @@ void APU::Run()
|
||||
//-When a DMC or FrameCounter interrupt needs to be fired
|
||||
int32_t cyclesToRun = _currentCycle - _previousCycle;
|
||||
|
||||
while(_previousCycle < _currentCycle) {
|
||||
while(cyclesToRun > 0) {
|
||||
_previousCycle += _frameCounter->Run(cyclesToRun);
|
||||
|
||||
//Reload counters set by writes to 4003/4008/400B/400F after running the frame counter to allow the length counter to be clocked first
|
||||
|
19
Core/CPU.h
19
Core/CPU.h
@ -148,22 +148,24 @@ private:
|
||||
|
||||
void MemoryWrite(uint16_t addr, uint8_t value)
|
||||
{
|
||||
if(_dmcCounter == 4) {
|
||||
_dmcCounter = 3;
|
||||
}
|
||||
|
||||
while(_dmcDmaRunning) {
|
||||
IncCycleCount();
|
||||
}
|
||||
|
||||
_cpuWrite = true;;
|
||||
_writeAddr = addr;
|
||||
IncCycleCount();
|
||||
while(_dmcDmaRunning) {
|
||||
IncCycleCount();
|
||||
}
|
||||
_memoryManager->Write(addr, value);
|
||||
|
||||
//DMA DMC might have started after a write to $4015, stall CPU if needed
|
||||
while (_dmcDmaRunning) {
|
||||
IncCycleCount();
|
||||
}
|
||||
_cpuWrite = false;
|
||||
|
||||
}
|
||||
|
||||
uint8_t MemoryRead(uint16_t addr, MemoryOperationType operationType = MemoryOperationType::Read) {
|
||||
IncCycleCount();
|
||||
while(_dmcDmaRunning) {
|
||||
//Stall CPU until we can process a DMC read
|
||||
if((addr != 0x4016 && addr != 0x4017 && (_cycleCount & 0x01)) || _dmcCounter == 1) {
|
||||
@ -175,7 +177,6 @@ private:
|
||||
}
|
||||
IncCycleCount();
|
||||
}
|
||||
IncCycleCount();
|
||||
uint8_t value = _memoryManager->Read(addr, operationType);
|
||||
return value;
|
||||
}
|
||||
|
@ -34,6 +34,9 @@ void DeltaModulationChannel::Reset(bool softReset)
|
||||
//Not sure if this is accurate, but it seems to make things better rather than worse (for dpcmletterbox)
|
||||
//"On the real thing, I think the power-on value is 428 (or the equivalent at least - it uses a linear feedback shift register), though only the even/oddness should matter for this test."
|
||||
_period = (GetNesModel() == NesModel::NTSC ? _dmcPeriodLookupTableNtsc : _dmcPeriodLookupTablePal)[0] - 1;
|
||||
|
||||
//Make sure the DMC doesn't tick on the first cycle - this is part of what keeps Sprite/DMC DMA tests working while fixing dmc_pitch.
|
||||
_timer = _period;
|
||||
}
|
||||
|
||||
void DeltaModulationChannel::InitSample()
|
||||
@ -163,7 +166,6 @@ void DeltaModulationChannel::WriteRAM(uint16_t addr, uint8_t value)
|
||||
|
||||
case 1: //4011
|
||||
_outputLevel = value & 0x7F;
|
||||
_shiftRegister = value & 0x7F;
|
||||
|
||||
//4011 applies new output right away, not on the timer's reload. This fixes bad DMC sound when playing through 4011.
|
||||
AddOutput(_outputLevel);
|
||||
|
Loading…
Reference in New Issue
Block a user