Updated frame advance to run after first advance when paused previously.
Moved frame events into the CPU core to prevent PPU<>NMI race condition.
Credit to r5 for pointing out there being an issue during frame advance.
This commit is contained in:
byuu 2019-10-12 14:28:03 +09:00
parent 3d646aef73
commit fb95d5b59f
5 changed files with 12 additions and 18 deletions

View File

@ -29,7 +29,7 @@ using namespace nall;
namespace Emulator { namespace Emulator {
static const string Name = "bsnes"; static const string Name = "bsnes";
static const string Version = "111.4"; static const string Version = "111.5";
static const string Author = "byuu"; static const string Author = "byuu";
static const string License = "GPLv3"; static const string License = "GPLv3";
static const string Website = "https://byuu.org"; static const string Website = "https://byuu.org";

View File

@ -123,6 +123,15 @@ auto CPU::scanline() -> void {
overclocking.target = clocks * overclock - clocks; overclocking.target = clocks * overclock - clocks;
} }
} }
//handle video frame events from the CPU core to prevent a race condition between
//games polling inputs during NMI and the PPU thread not being 100% synchronized.
if(vcounter() == ppu.vdisp()) {
if(auto device = controllerPort2.device) device->latch(); //light guns
synchronizePPU();
if(system.fastPPU()) PPUfast::Line::flush();
scheduler.leave(Scheduler::Event::Frame);
}
} }
auto CPU::aluEdge() -> void { auto CPU::aluEdge() -> void {

View File

@ -118,15 +118,9 @@ auto PPU::scanline() -> void {
} }
if(vcounter() == vdisp()) { if(vcounter() == vdisp()) {
if(auto device = controllerPort2.device) device->latch(); //light guns
if(!io.displayDisable) oamAddressReset(); if(!io.displayDisable) oamAddressReset();
} }
if(vcounter() == vdisp()) { //240
Line::flush();
scheduler.leave(Scheduler::Event::Frame);
}
if(vcounter() == 240) { if(vcounter() == 240) {
Line::flush(); Line::flush();
} }

View File

@ -17,14 +17,6 @@ auto PPU::main() -> void {
window.scanline(); window.scanline();
screen.scanline(); screen.scanline();
if(vcounter() == vdisp()) {
if(auto device = controllerPort2.device) device->latch(); //light guns
}
if(vcounter() == vdisp()) { //240
scheduler.leave(Scheduler::Event::Frame);
}
if(vcounter() > 240) { if(vcounter() > 240) {
step(hperiod()); step(hperiod());
return; return;

View File

@ -123,10 +123,9 @@ auto InputManager::bindHotkeys() -> void {
if(!presentation.frameAdvance.checked()) { if(!presentation.frameAdvance.checked()) {
//start frame advance if not currently frame advancing //start frame advance if not currently frame advancing
presentation.frameAdvance.setChecked().doActivate(); presentation.frameAdvance.setChecked().doActivate();
} else {
//advance to the next video frame otherwise
program.frameAdvanceLock = false;
} }
//advance one frame, even if we were currently paused when starting frame advance mode
program.frameAdvanceLock = false;
})); }));
hotkeys.append(InputHotkey("Increase HD Mode 7").onPress([] { hotkeys.append(InputHotkey("Increase HD Mode 7").onPress([] {