snes: ppu: state out similarly to apu. this was a very simple project; unlike the apu, there aren't many sync points. like the apu, a message is dumped to the console if runtosave causes determinism problems. like the apu, there's no speed hit, but tales of phantasia is still broken. breaks savesates.
This commit is contained in:
parent
fb2a80b7d9
commit
74c26d9b11
Binary file not shown.
|
@ -16,7 +16,10 @@ void PPU::step(unsigned clocks) {
|
||||||
|
|
||||||
void PPU::synchronize_cpu() {
|
void PPU::synchronize_cpu() {
|
||||||
if(CPU::Threaded == true) {
|
if(CPU::Threaded == true) {
|
||||||
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
|
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All)
|
||||||
|
co_switch(cpu.thread);
|
||||||
|
else if(clock >= 0 && scheduler.sync == Scheduler::SynchronizeMode::All)
|
||||||
|
interface->message("PPU had to advance nondeterministically!");
|
||||||
} else {
|
} else {
|
||||||
while(clock >= 0) cpu.enter();
|
while(clock >= 0) cpu.enter();
|
||||||
}
|
}
|
||||||
|
@ -28,12 +31,27 @@ void PPU::enter() {
|
||||||
while(true) {
|
while(true) {
|
||||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch(uindex)
|
||||||
|
{
|
||||||
|
case 0: enter1(); break;
|
||||||
|
case 1: enter2(); break;
|
||||||
|
case 2: enter3(); break;
|
||||||
|
case 3: enter4(); break;
|
||||||
|
}
|
||||||
|
uindex++;
|
||||||
|
uindex &= 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PPU::enter1() {
|
||||||
//H = 0 (initialize)
|
//H = 0 (initialize)
|
||||||
scanline();
|
scanline();
|
||||||
add_clocks(10);
|
add_clocks(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PPU::enter2() {
|
||||||
//H = 10 (cache mode7 registers + OAM address reset)
|
//H = 10 (cache mode7 registers + OAM address reset)
|
||||||
cache.m7_hofs = regs.m7_hofs;
|
cache.m7_hofs = regs.m7_hofs;
|
||||||
cache.m7_vofs = regs.m7_vofs;
|
cache.m7_vofs = regs.m7_vofs;
|
||||||
|
@ -50,11 +68,15 @@ void PPU::enter() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
add_clocks(502);
|
add_clocks(502);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PPU::enter3() {
|
||||||
//H = 512 (render)
|
//H = 512 (render)
|
||||||
render_scanline();
|
render_scanline();
|
||||||
add_clocks(640);
|
add_clocks(640);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PPU::enter4() {
|
||||||
//H = 1152 (cache OBSEL)
|
//H = 1152 (cache OBSEL)
|
||||||
if(cache.oam_basesize != regs.oam_basesize) {
|
if(cache.oam_basesize != regs.oam_basesize) {
|
||||||
cache.oam_basesize = regs.oam_basesize;
|
cache.oam_basesize = regs.oam_basesize;
|
||||||
|
@ -63,8 +85,6 @@ void PPU::enter() {
|
||||||
cache.oam_nameselect = regs.oam_nameselect;
|
cache.oam_nameselect = regs.oam_nameselect;
|
||||||
cache.oam_tdaddr = regs.oam_tdaddr;
|
cache.oam_tdaddr = regs.oam_tdaddr;
|
||||||
add_clocks(lineclocks() - 1152); //seek to start of next scanline
|
add_clocks(lineclocks() - 1152); //seek to start of next scanline
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPU::add_clocks(unsigned clocks) {
|
void PPU::add_clocks(unsigned clocks) {
|
||||||
|
@ -349,6 +369,8 @@ void PPU::reset() {
|
||||||
create(Enter, system.cpu_frequency());
|
create(Enter, system.cpu_frequency());
|
||||||
PPUcounter::reset();
|
PPUcounter::reset();
|
||||||
memset(surface, 0, 512 * 512 * sizeof(uint32));
|
memset(surface, 0, 512 * 512 * sizeof(uint32));
|
||||||
|
|
||||||
|
uindex = 0;
|
||||||
|
|
||||||
//zero 01-dec-2012 - gotta reset these sometime, somewhere
|
//zero 01-dec-2012 - gotta reset these sometime, somewhere
|
||||||
memset(oam_itemlist, 0, sizeof(oam_itemlist));
|
memset(oam_itemlist, 0, sizeof(oam_itemlist));
|
||||||
|
|
|
@ -11,6 +11,8 @@ public:
|
||||||
#include "memory/memory.hpp"
|
#include "memory/memory.hpp"
|
||||||
#include "mmio/mmio.hpp"
|
#include "mmio/mmio.hpp"
|
||||||
#include "render/render.hpp"
|
#include "render/render.hpp"
|
||||||
|
|
||||||
|
int uindex;
|
||||||
|
|
||||||
uint32 *surface;
|
uint32 *surface;
|
||||||
uint32 *output;
|
uint32 *output;
|
||||||
|
@ -58,7 +60,11 @@ public:
|
||||||
void scanline();
|
void scanline();
|
||||||
void render_scanline();
|
void render_scanline();
|
||||||
void frame();
|
void frame();
|
||||||
void enter();
|
void enter();
|
||||||
|
void enter1();
|
||||||
|
void enter2();
|
||||||
|
void enter3();
|
||||||
|
void enter4();
|
||||||
void enable();
|
void enable();
|
||||||
void power();
|
void power();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -201,7 +201,9 @@ void PPU::serialize(serializer &s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s.array(oam_line_pal, 256);
|
s.array(oam_line_pal, 256);
|
||||||
s.array(oam_line_pri, 256);
|
s.array(oam_line_pri, 256);
|
||||||
|
|
||||||
|
s.integer(uindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue