2016-01-27 11:31:39 +00:00
|
|
|
#include <ws/ws.hpp>
|
|
|
|
|
|
|
|
namespace WonderSwan {
|
|
|
|
|
|
|
|
PPU ppu;
|
2016-02-04 10:29:08 +00:00
|
|
|
#include "io.cpp"
|
2016-01-27 11:31:39 +00:00
|
|
|
#include "video.cpp"
|
|
|
|
|
|
|
|
auto PPU::Enter() -> void {
|
|
|
|
ppu.main();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto PPU::main() -> void {
|
|
|
|
while(true) {
|
|
|
|
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
|
|
|
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
step(256);
|
2016-02-04 21:18:06 +00:00
|
|
|
scanline();
|
|
|
|
}
|
|
|
|
}
|
2016-01-27 11:31:39 +00:00
|
|
|
|
2016-02-04 21:18:06 +00:00
|
|
|
auto PPU::scanline() -> void {
|
|
|
|
status.hclk = 0;
|
|
|
|
status.vclk++;
|
|
|
|
if(status.vclk == 144) {
|
|
|
|
cpu.raise(CPU::Interrupt::Vblank);
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
2016-02-04 21:18:06 +00:00
|
|
|
if(status.vclk == 159) frame();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto PPU::frame() -> void {
|
|
|
|
status.vclk = 0;
|
|
|
|
video.refresh();
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto PPU::step(uint clocks) -> void {
|
|
|
|
status.hclk += clocks;
|
|
|
|
|
|
|
|
clock += clocks;
|
|
|
|
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto PPU::power() -> void {
|
|
|
|
create(PPU::Enter, 3072000);
|
|
|
|
|
2016-02-04 10:29:08 +00:00
|
|
|
for(uint n = 0x0000; n <= 0x0001; n++) iomap[n] = this;
|
|
|
|
for(uint n = 0x0004; n <= 0x0007; n++) iomap[n] = this;
|
|
|
|
for(uint n = 0x0010; n <= 0x0015; n++) iomap[n] = this;
|
|
|
|
for(uint n = 0x001c; n <= 0x001f; n++) iomap[n] = this;
|
|
|
|
iomap[0x0060] = this;
|
|
|
|
|
2016-01-27 11:31:39 +00:00
|
|
|
for(auto& n : output) n = 0;
|
|
|
|
|
|
|
|
status.vclk = 0;
|
|
|
|
status.hclk = 0;
|
2016-01-28 11:39:49 +00:00
|
|
|
|
|
|
|
video.power();
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|