mirror of https://github.com/bsnes-emu/bsnes.git
119 lines
2.7 KiB
C++
119 lines
2.7 KiB
C++
#include <pce/pce.hpp>
|
|
|
|
namespace PCEngine {
|
|
|
|
VDC vdc0;
|
|
VDC vdc1;
|
|
#include "memory.cpp"
|
|
#include "io.cpp"
|
|
#include "irq.cpp"
|
|
#include "dma.cpp"
|
|
#include "background.cpp"
|
|
#include "sprite.cpp"
|
|
#include "serialization.cpp"
|
|
|
|
auto VDC::Enter() -> void {
|
|
while(true) {
|
|
scheduler.synchronize();
|
|
if(vdc0.active()) vdc0.main();
|
|
if(vdc1.active()) vdc1.main();
|
|
}
|
|
}
|
|
|
|
auto VDC::main() -> void {
|
|
if(Model::PCEngine() && vdc1.active()) return step(frequency());
|
|
|
|
timing.vpulse = false;
|
|
timing.vclock = 0;
|
|
timing.voffset = 0;
|
|
timing.vstart = max((uint8)2, timing.verticalDisplayStart) - 2;
|
|
timing.vlength = min(242, timing.verticalDisplayLength + 1);
|
|
|
|
while(!timing.vpulse) {
|
|
timing.hpulse = false;
|
|
timing.hclock = 0;
|
|
timing.hoffset = 0;
|
|
timing.hstart = timing.horizontalDisplayStart;
|
|
timing.hlength = (timing.horizontalDisplayLength + 1) << 3;
|
|
|
|
if(timing.vclock >= timing.vstart && timing.voffset < timing.vlength) {
|
|
background.scanline(timing.voffset);
|
|
sprite.scanline(timing.voffset);
|
|
|
|
step(timing.hstart);
|
|
|
|
while(timing.hoffset < timing.hlength) {
|
|
data = 0;
|
|
|
|
background.run(timing.hoffset, timing.voffset);
|
|
sprite.run(timing.hoffset, timing.voffset);
|
|
|
|
if(sprite.color && sprite.priority) {
|
|
data = 1 << 8 | sprite.palette << 4 | sprite.color << 0;
|
|
} else if(background.color) {
|
|
data = 0 << 8 | background.palette << 4 | background.color << 0;
|
|
} else if(sprite.color) {
|
|
data = 1 << 8 | sprite.palette << 4 | sprite.color << 0;
|
|
}
|
|
|
|
step(vce.clock());
|
|
timing.hoffset++;
|
|
}
|
|
data = 0;
|
|
|
|
if(timing.voffset == io.lineCoincidence - 64) {
|
|
irq.raise(IRQ::Line::LineCoincidence);
|
|
}
|
|
|
|
while(!timing.hpulse) step(1);
|
|
timing.vclock++;
|
|
timing.voffset++;
|
|
} else {
|
|
data = 0;
|
|
while(!timing.hpulse) step(1);
|
|
timing.vclock++;
|
|
}
|
|
|
|
if(timing.vclock == timing.vstart + timing.vlength) {
|
|
irq.raise(IRQ::Line::Vblank);
|
|
dma.satbStart();
|
|
}
|
|
}
|
|
}
|
|
|
|
auto VDC::scanline() -> void {
|
|
timing.hpulse = true;
|
|
}
|
|
|
|
auto VDC::frame() -> void {
|
|
timing.vpulse = true;
|
|
}
|
|
|
|
auto VDC::step(uint clocks) -> void {
|
|
Thread::step(clocks);
|
|
synchronize(cpu);
|
|
synchronize(vce);
|
|
|
|
timing.hclock += clocks;
|
|
dma.step(clocks);
|
|
}
|
|
|
|
auto VDC::power() -> void {
|
|
create(VDC::Enter, system.colorburst() * 6.0);
|
|
|
|
memory::fill(&vram, sizeof(VRAM));
|
|
memory::fill(&satb, sizeof(SATB));
|
|
memory::fill(&timing, sizeof(Timing));
|
|
memory::fill(&irq, sizeof(IRQ));
|
|
memory::fill(&dma, sizeof(DMA));
|
|
memory::fill(&io, sizeof(IO));
|
|
memory::fill(&background, sizeof(Background));
|
|
memory::fill(&sprite, sizeof(Sprite));
|
|
|
|
dma.vdc = this;
|
|
background.vdc = this;
|
|
sprite.vdc = this;
|
|
}
|
|
|
|
}
|