Files
bsnes/sfc/alt/cpu/timing.cpp
Tim Allen 78d49d3873 Update to v095r10 release.
byuu says:

Changelog:

- int_t<bits> replaced with Integer<bits>
- uint_t<bits> replaced with Natural<bits>
- fixed "Synchronize Audio" menu option that broke recently
- all of sfc/performance ported to "auto function() -> return;" syntax

With this WIP, all of higan is finally ported over to the new function
declaration syntax. Thank the gods.

There's still going to be periodic disruption for diffs from porting
over signed->int, unsigned->uint, and whatever we come up with for the
new Natural<> and Integer<> classes. But the worst of it's behind us
now.
2015-12-07 08:11:41 +11:00

116 lines
3.3 KiB
C++

auto CPU::queue_event(uint id) -> void {
switch(id) {
case QueueEvent::DramRefresh: return add_clocks(40);
case QueueEvent::HdmaRun: return hdma_run();
}
}
auto CPU::last_cycle() -> void {
if(status.irq_lock) {
status.irq_lock = false;
return;
}
if(status.nmi_transition) {
regs.wai = false;
status.nmi_transition = false;
status.nmi_pending = true;
}
if(status.irq_transition || regs.irq) {
regs.wai = false;
status.irq_transition = false;
status.irq_pending = !regs.p.i;
}
}
auto CPU::add_clocks(uint clocks) -> void {
if(status.hirq_enabled) {
if(status.virq_enabled) {
uint cpu_time = vcounter() * 1364 + hcounter();
uint irq_time = status.vtime * 1364 + status.htime * 4;
uint framelines = (system.region() == System::Region::NTSC ? 262 : 312) + (ppu.interlace() && !field());
if(cpu_time > irq_time) irq_time += framelines * 1364;
bool irq_valid = status.irq_valid;
status.irq_valid = cpu_time <= irq_time && cpu_time + clocks > irq_time;
if(!irq_valid && status.irq_valid) status.irq_line = true;
} else {
uint irq_time = status.htime * 4;
if(hcounter() > irq_time) irq_time += 1364;
bool irq_valid = status.irq_valid;
status.irq_valid = hcounter() <= irq_time && hcounter() + clocks > irq_time;
if(!irq_valid && status.irq_valid) status.irq_line = true;
}
if(status.irq_line) status.irq_transition = true;
} else if(status.virq_enabled) {
bool irq_valid = status.irq_valid;
status.irq_valid = vcounter() == status.vtime;
if(!irq_valid && status.irq_valid) status.irq_line = true;
if(status.irq_line) status.irq_transition = true;
} else {
status.irq_valid = false;
}
tick(clocks);
queue.tick(clocks);
step(clocks);
}
auto CPU::scanline() -> void {
synchronizeSMP();
synchronizePPU();
synchronizeCoprocessors();
system.scanline();
if(vcounter() == 0) hdma_init();
queue.enqueue(534, QueueEvent::DramRefresh);
if(vcounter() <= (ppu.overscan() == false ? 224 : 239)) {
queue.enqueue(1104 + 8, QueueEvent::HdmaRun);
}
bool nmi_valid = status.nmi_valid;
status.nmi_valid = vcounter() >= (ppu.overscan() == false ? 225 : 240);
if(!nmi_valid && status.nmi_valid) {
status.nmi_line = true;
if(status.nmi_enabled) status.nmi_transition = true;
} else if(nmi_valid && !status.nmi_valid) {
status.nmi_line = false;
}
if(status.auto_joypad_poll_enabled && vcounter() == (ppu.overscan() == false ? 227 : 242)) {
run_auto_joypad_poll();
}
}
auto CPU::run_auto_joypad_poll() -> void {
device.controllerPort1->latch(1);
device.controllerPort2->latch(1);
device.controllerPort1->latch(0);
device.controllerPort2->latch(0);
uint16 joy1 = 0, joy2 = 0, joy3 = 0, joy4 = 0;
for(uint i = 0; i < 16; i++) {
uint8 port0 = device.controllerPort1->data();
uint8 port1 = device.controllerPort2->data();
joy1 |= (port0 & 1) ? (0x8000 >> i) : 0;
joy2 |= (port1 & 1) ? (0x8000 >> i) : 0;
joy3 |= (port0 & 2) ? (0x8000 >> i) : 0;
joy4 |= (port1 & 2) ? (0x8000 >> i) : 0;
}
status.joy1l = joy1;
status.joy1h = joy1 >> 8;
status.joy2l = joy2;
status.joy2h = joy2 >> 8;
status.joy3l = joy3;
status.joy3h = joy3 >> 8;
status.joy4l = joy4;
status.joy4h = joy4 >> 8;
}