Skip to content

Commit

Permalink
NES: Added option to enable CPU test mode registers
Browse files Browse the repository at this point in the history
  • Loading branch information
SourMesen committed Sep 28, 2024
1 parent ab8f9f6 commit de20208
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 13 deletions.
1 change: 1 addition & 0 deletions Core/NES/APU/DeltaModulationChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@ class DeltaModulationChannel : public INesMemoryHandler, public ISerializable
uint16_t GetDmcReadAddress();
void SetDmcReadBuffer(uint8_t value);

uint8_t GetOutput() { return _timer.GetLastOutput(); }
ApuDmcState GetState();
};
24 changes: 20 additions & 4 deletions Core/NES/APU/NesApu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,27 @@ uint8_t NesApu::ReadRam(uint16_t addr)
//$4015 read
Run();

uint8_t status = GetStatus() | (_console->GetMemoryManager()->GetInternalOpenBus() & 0x20);
if(addr >= 0x4018 && !_console->GetNesConfig().EnableCpuTestMode) {
return _console->GetMemoryManager()->GetOpenBus();
}

//Reading $4015 clears the Frame Counter interrupt flag.
_console->GetCpu()->ClearIrqSource(IRQSource::FrameCounter);
switch(addr) {
case 0x4015: {
uint8_t status = GetStatus() | (_console->GetMemoryManager()->GetInternalOpenBus() & 0x20);

return status;
//Reading $4015 clears the Frame Counter interrupt flag.
_console->GetCpu()->ClearIrqSource(IRQSource::FrameCounter);

return status;
}

case 0x4018: return _square1->GetOutput() | (_square2->GetOutput() << 4);
case 0x4019: return _triangle->GetOutput() | (_noise->GetOutput() << 4);
case 0x401A: return _dmc->GetOutput();

default:
return _console->GetMemoryManager()->GetOpenBus();
}
}

uint8_t NesApu::PeekRam(uint16_t addr)
Expand Down Expand Up @@ -126,6 +141,7 @@ void NesApu::WriteRam(uint16_t addr, uint8_t value)
void NesApu::GetMemoryRanges(MemoryRanges &ranges)
{
ranges.AddHandler(MemoryOperation::Read, 0x4015);
ranges.AddHandler(MemoryOperation::Read, 0x4018, 0x401A);
ranges.AddHandler(MemoryOperation::Write, 0x4015);
}

Expand Down
5 changes: 5 additions & 0 deletions Core/NES/APU/NoiseChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ class NoiseChannel : public INesMemoryHandler, public ISerializable
}
}

uint8_t GetOutput()
{
return _timer.GetLastOutput();
}

ApuNoiseState GetState()
{
ApuNoiseState state;
Expand Down
5 changes: 5 additions & 0 deletions Core/NES/APU/SquareChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ class SquareChannel : public INesMemoryHandler, public ISerializable
return _envelope.LengthCounter.GetStatus();
}

uint8_t GetOutput()
{
return _timer.GetLastOutput();
}

ApuSquareState GetState()
{
ApuSquareState state;
Expand Down
5 changes: 5 additions & 0 deletions Core/NES/APU/TriangleChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ class TriangleChannel : public INesMemoryHandler, public ISerializable
return _lengthCounter.GetStatus();
}

uint8_t GetOutput()
{
return _timer.GetLastOutput();
}

ApuTriangleState GetState()
{
ApuTriangleState state;
Expand Down
4 changes: 2 additions & 2 deletions Core/NES/BaseMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,8 @@ void BaseMapper::GetMemoryRanges(MemoryRanges &ranges)
ranges.AddHandler(MemoryOperation::Read, 0x6000, 0xFFFF);
ranges.AddHandler(MemoryOperation::Write, 0x6000, 0xFFFF);
} else {
ranges.AddHandler(MemoryOperation::Read, 0x4018, 0xFFFF);
ranges.AddHandler(MemoryOperation::Write, 0x4018, 0xFFFF);
ranges.AddHandler(MemoryOperation::Read, 0x4020, 0xFFFF);
ranges.AddHandler(MemoryOperation::Write, 0x4020, 0xFFFF);
}
}

Expand Down
4 changes: 2 additions & 2 deletions Core/NES/Debugger/NesDebugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,9 @@ bool NesDebugger::IsRegister(MemoryOperationInfo& op)
return true;
} else if((op.Address >= 0x4000 && op.Address <= 0x4015) || (op.Address == 0x4017 && op.Type == MemoryOperationType::Write)) {
return true;
} else if(op.Address == 0x4016 || (op.Address == 0x4017 && op.Type == MemoryOperationType::Read)) {
} else if(op.Address == 0x4016 || (op.Address >= 0x4017 && op.Address <= 0x401A && op.Type == MemoryOperationType::Read)) {
return true;
} else if(op.Address >= 0x4018 && ((op.Type == MemoryOperationType::Write && _mapper->IsWriteRegister(op.Address)) || (op.Type == MemoryOperationType::Read && _mapper->IsReadRegister(op.Address)))) {
} else if(op.Address >= 0x4020 && ((op.Type == MemoryOperationType::Write && _mapper->IsWriteRegister(op.Address)) || (op.Type == MemoryOperationType::Read && _mapper->IsReadRegister(op.Address)))) {
return true;
}
return false;
Expand Down
8 changes: 4 additions & 4 deletions Core/NES/Debugger/NesEventManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ EventViewerCategoryCfg NesEventManager::GetEventConfig(DebugEventInfo& evt)
case 0x2006: return _config.Ppu2006Write;
case 0x2007: return _config.Ppu2007Write;
}
} else if(addr >= 0x4018 && _mapper->IsWriteRegister(addr)) {
} else if(addr >= 0x4020 && _mapper->IsWriteRegister(addr)) {
return _config.MapperRegisterWrites;
} else if((addr >= 0x4000 && addr <= 0x4015) || addr == 0x4017) {
} else if((addr >= 0x4000 && addr <= 0x4015) || addr == 0x4017 || addr == 0x401A) {
return _config.ApuRegisterWrites;
} else if(addr == 0x4016) {
return _config.ControlRegisterWrites;
Expand All @@ -183,9 +183,9 @@ EventViewerCategoryCfg NesEventManager::GetEventConfig(DebugEventInfo& evt)
case 0x2004: return _config.Ppu2004Read;
case 0x2007: return _config.Ppu2007Read;
}
} else if(addr >= 0x4018 && _mapper->IsReadRegister(addr)) {
} else if(addr >= 0x4020 && _mapper->IsReadRegister(addr)) {
return _config.MapperRegisterReads;
} else if(addr >= 0x4000 && addr <= 0x4015) {
} else if((addr >= 0x4000 && addr <= 0x4015) || (addr >= 0x4018 && addr <= 0x401A)) {
return _config.ApuRegisterReads;
} else if(addr == 0x4016 || addr == 0x4017) {
return _config.ControlRegisterReads;
Expand Down
1 change: 1 addition & 0 deletions Core/Shared/SettingTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@ struct NesConfig
bool EnablePpu2006ScrollGlitch = false;
bool RestrictPpuAccessOnFirstFrame = false;
bool EnableDmcSampleDuplicationGlitch = false;
bool EnableCpuTestMode = false;

bool RandomizeMapperPowerOnState = false;
bool RandomizeCpuPpuAlignment = false;
Expand Down
5 changes: 4 additions & 1 deletion UI/Config/NesConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ public class NesConfig : BaseConfig<NesConfig>
[Reactive] public bool EnablePpu2006ScrollGlitch { get; set; } = false;
[Reactive] public bool RestrictPpuAccessOnFirstFrame { get; set; } = false;
[Reactive] public bool EnableDmcSampleDuplicationGlitch { get; set; } = false;

[Reactive] public bool EnableCpuTestMode { get; set; } = false;

[Reactive] public NesConsoleType ConsoleType { get; set; } = NesConsoleType.Nes001;
[Reactive] public bool DisablePpuReset { get; set; } = false;
[Reactive] public bool AllowInvalidInput { get; set; } = false;
Expand Down Expand Up @@ -191,6 +192,7 @@ public void ApplyConfig()
EnablePpu2006ScrollGlitch = EnablePpu2006ScrollGlitch,
RestrictPpuAccessOnFirstFrame = RestrictPpuAccessOnFirstFrame,
EnableDmcSampleDuplicationGlitch = EnableDmcSampleDuplicationGlitch,
EnableCpuTestMode = EnableCpuTestMode,

RandomizeMapperPowerOnState = RandomizeMapperPowerOnState,
RandomizeCpuPpuAlignment = RandomizeCpuPpuAlignment,
Expand Down Expand Up @@ -323,6 +325,7 @@ public struct InteropNesConfig
[MarshalAs(UnmanagedType.I1)] public bool EnablePpu2006ScrollGlitch;
[MarshalAs(UnmanagedType.I1)] public bool RestrictPpuAccessOnFirstFrame;
[MarshalAs(UnmanagedType.I1)] public bool EnableDmcSampleDuplicationGlitch;
[MarshalAs(UnmanagedType.I1)] public bool EnableCpuTestMode;

[MarshalAs(UnmanagedType.I1)] public bool RandomizeMapperPowerOnState;
[MarshalAs(UnmanagedType.I1)] public bool RandomizeCpuPpuAlignment;
Expand Down
1 change: 1 addition & 0 deletions UI/Localization/resources.en.xml
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@
<Control ID="chkDisableGameGenieBusConflicts">Disable Game Genie bus conflict emulation</Control>
<Control ID="chkDisableFlashSaves">Disable flash saves (UNROM512 / GTROM)</Control>
<Control ID="chkEnableDmcSampleDuplicationGlitch">Enable DMC sample duplication glitch (late-G &amp; H CPU behavior)</Control>
<Control ID="chkEnableCpuTestMode">Enable CPU test mode registers</Control>
<Control ID="lblConsoleType">Console model:</Control>
<Control ID="chkAllowInvalidInput">Allow invalid input (e.g Down + Up or Left + Right at the same time)</Control>
</Form>
Expand Down
1 change: 1 addition & 0 deletions UI/Views/NesConfigView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@
<c:CheckBoxWarning IsChecked="{Binding Config.DisableOamAddrBug}" Text="{l:Translate chkDisableOamAddrBug}" />
<c:CheckBoxWarning IsChecked="{Binding Config.DisablePaletteRead}" Text="{l:Translate chkDisablePaletteRead}" />
<c:CheckBoxWarning IsChecked="{Binding Config.DisablePpu2004Reads}" Text="{l:Translate chkDisablePpu2004Reads}" />
<c:CheckBoxWarning IsChecked="{Binding Config.EnableCpuTestMode}" Text="{l:Translate chkEnableCpuTestMode}" />
<c:CheckBoxWarning IsChecked="{Binding Config.EnableDmcSampleDuplicationGlitch}" Text="{l:Translate chkEnableDmcSampleDuplicationGlitch}" />
<c:CheckBoxWarning IsChecked="{Binding Config.DisableGameGenieBusConflicts}" Text="{l:Translate chkDisableGameGenieBusConflicts}" />
<c:CheckBoxWarning IsChecked="{Binding Config.DisableFlashSaves}" Text="{l:Translate chkDisableFlashSaves}" />
Expand Down

0 comments on commit de20208

Please sign in to comment.