Skip to content

Commit

Permalink
Working 2x overclocking (meepingsnesroms)
Browse files Browse the repository at this point in the history
  • Loading branch information
rdanbrook committed Sep 20, 2017
1 parent d86e1ad commit 65245e4
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 0 deletions.
11 changes: 11 additions & 0 deletions libretro/libretro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ void retro_set_environment(retro_environment_t cb)
{ "nestopia_blargg_ntsc_filter", "Blargg NTSC filter; disabled|composite|svideo|rgb|monochrome" },
{ "nestopia_palette", "Palette; cxa2025as|consumer|canonical|alternative|rgb|pal|composite-direct-fbx|pvm-style-d93-fbx|ntsc-hardware-fbx|nes-classic-fbx-fs|raw|custom" },
{ "nestopia_nospritelimit", "Remove 8-sprites-per-scanline hardware limit; disabled|enabled" },
{ "nestopia_overclock", "CPU Speed (Overclock); 1x|2x" },
{ "nestopia_fds_auto_insert", "Automatically insert first FDS disk on reset; enabled|disabled" },
{ "nestopia_overscan_v", "Mask Overscan (Vertical); enabled|disabled" },
{ "nestopia_overscan_h", "Mask Overscan (Horizontal); disabled|enabled" },
Expand Down Expand Up @@ -605,6 +606,16 @@ static void check_variables(void)
video.EnableUnlimSprites(true);
}

var.key = "nestopia_overclock";

if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
{
if (strcmp(var.value, "1x") == 0)
video.EnableOverclocking(false);
else if (strcmp(var.value, "2x") == 0)
video.EnableOverclocking(true);
}

var.key = "nestopia_fds_auto_insert";

if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
Expand Down
16 changes: 16 additions & 0 deletions source/core/NstApu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1961,6 +1961,7 @@ namespace Nes
dma.buffered = false;
dma.address = 0xC000;
dma.buffer = 0x00;
overclockingIsSafe = true;
}

Cycle Apu::Dmc::GetResetFrequency(CpuModel model)
Expand Down Expand Up @@ -2174,16 +2175,31 @@ namespace Nes
{
out.dac = data & 0x7F;
curSample = out.dac * outputVolume;

if (out.dac != 0)
{
overclockingIsSafe = false;
}
}

NST_SINGLE_CALL void Apu::Dmc::WriteReg2(const uint data)
{
regs.address = 0xC000 | (data << 6);

if (regs.address != 0)
{
overclockingIsSafe = true;
}
}

NST_SINGLE_CALL void Apu::Dmc::WriteReg3(const uint data)
{
regs.lengthCounter = (data << 4) + 1;

if (regs.lengthCounter != 0)
{
overclockingIsSafe = true;
}
}

NST_SINGLE_CALL bool Apu::Dmc::ClockDAC()
Expand Down
12 changes: 12 additions & 0 deletions source/core/NstApu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,8 @@ namespace Nes

Dmc();

bool overclockingIsSafe;

void Reset(CpuModel);
void UpdateSettings(uint);
void LoadState(State::Loader&,const Cpu&,CpuModel,Cycle&);
Expand Down Expand Up @@ -624,6 +626,16 @@ namespace Nes

public:

void SetOverclockSafety(bool safe)
{
dmc.overclockingIsSafe = safe;
}

bool GetOverclockSafety()
{
return dmc.overclockingIsSafe;
}

dword GetSampleRate() const
{
return settings.rate;
Expand Down
14 changes: 14 additions & 0 deletions source/core/NstCpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ namespace Nes
ticks = 0;
logged = 0;

cpuOverclocking = false;

pc = RESET_VECTOR;

cycles.count = 0;
Expand Down Expand Up @@ -1899,6 +1901,18 @@ namespace Nes

if (interrupt.irqClock != CYCLE_MAX)
interrupt.irqClock = (interrupt.irqClock > cycles.frame ? interrupt.irqClock - cycles.frame : 0);

if (cpuOverclocking)
{
uint startCycle = cycles.count;
uint lastCycle = cycles.count + extraCycles;
do
{
ExecuteOp();
}
while (cycles.count < extraCycles);
cycles.count = startCycle;
}
}

void Cpu::Clock()
Expand Down
8 changes: 8 additions & 0 deletions source/core/NstCpu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,8 @@ namespace Nes
Ram ram;
Apu apu;
IoMap map;
bool cpuOverclocking;
uint extraCycles;

static dword logged;
static void (Cpu::*const opcodes[0x100])();
Expand All @@ -499,6 +501,12 @@ namespace Nes
return apu;
}

void SetOverclocking(bool overclocking,uint newCycles)
{
cpuOverclocking = overclocking;
extraCycles = newCycles;
}

Cycle Update(uint readAddress=0)
{
apu.ClockDMA( readAddress );
Expand Down
33 changes: 33 additions & 0 deletions source/core/NstPpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ namespace Nes
yuvMap (NULL)
{
cycles.one = PPU_RP2C02_CC;
overclocked = false;
PowerOff();
}

Expand Down Expand Up @@ -555,6 +556,38 @@ namespace Nes
break;
}

if (overclocked)
{
Apu& audioSafeOverclock = cpu.GetApu();
if (audioSafeOverclock.GetOverclockSafety())
{
switch (model)
{
case PPU_RP2C02:
default:

cpu.SetOverclocking(true,PPU_RP2C02_HSYNC * PPU_RP2C02_VACTIVE);
break;

case PPU_RP2C07:

cpu.SetOverclocking(true,PPU_RP2C07_HSYNC * PPU_RP2C07_VACTIVE);
break;

case PPU_DENDY:

cpu.SetOverclocking(true,PPU_DENDY_HSYNC * PPU_DENDY_VACTIVE);
break;
}
}
else
{
cpu.SetOverclocking(false,0);
}

audioSafeOverclock.SetOverclockSafety(true);//overclocking is only safe if direct pcm audio has not been written for one frame
}

cpu.SetFrameCycles( frame );
}

Expand Down
11 changes: 11 additions & 0 deletions source/core/NstPpu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ namespace Nes
int scanline;
int scanline_sleep;
int ssleep;
bool overclocked;

PpuModel model;
Hook hActiveHook;
Expand Down Expand Up @@ -542,6 +543,16 @@ namespace Nes
{
return oam.spriteLimit;
}

bool GetOverclockState() const
{
return overclocked;
}

void SetOverclockState(bool overclock2x)
{
overclocked = overclock2x;
}
};
}
}
Expand Down
14 changes: 14 additions & 0 deletions source/core/api/NstApiVideo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ namespace Nes
return RESULT_NOP;
}

Result Video::EnableOverclocking(bool state) throw()
{
if (emulator.tracker.IsLocked( true ))
return RESULT_ERR_NOT_READY;

if (emulator.ppu.GetOverclockState() != state)
{
emulator.ppu.SetOverclockState( state );
return RESULT_OK;
}

return RESULT_NOP;
}

bool Video::AreUnlimSpritesEnabled() const throw()
{
return !emulator.ppu.HasSpriteLimit();
Expand Down
5 changes: 5 additions & 0 deletions source/core/api/NstApiVideo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ namespace Nes
* @return result code
*/
Result EnableUnlimSprites(bool state) throw();

/**
* Adds extra scanlines to fix lag
*/
Result EnableOverclocking(bool state) throw();

/**
* Checks if the PPU sprite software extension is enabled.
Expand Down

0 comments on commit 65245e4

Please sign in to comment.