bsnes/snes/smp/smp.cpp

128 lines
2.3 KiB
C++
Raw Normal View History

#include <snes.hpp>
#define SMP_CPP
namespace SNES {
#if defined(DEBUGGER)
#include "debugger/debugger.cpp"
SMPDebugger smp;
#else
SMP smp;
#endif
#include "serialization.cpp"
#include "iplrom.cpp"
#include "memory/memory.cpp"
#include "timing/timing.cpp"
void SMP::step(unsigned clocks) {
clock += clocks * (uint64)cpu.frequency;
dsp.clock -= clocks;
}
void SMP::synchronize_cpu() {
if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
}
void SMP::synchronize_dsp() {
Updated to 20100813 release. byuu says: Since we're now talking about three splits, that's getting a bit out of hand. This WIP combines everything back into one project again. Added the src/fast folder that has all the speed-oriented cores. A slight slowdown to csnes from what it was before, I'm using blargg's accurate DSP. I just don't like the idea of releasing a less accurate DSP core than Snes9X v1.52 has. Plus the fast DSP core doesn't serialize yet. I moved back to snes_spc 0.9.0 because I care more about Tales and Star Ocean than I do about Earthworm Jim 2. So if you try EWJ2 on csnes, expect it to sound like it does on Snes9X. In other words, don't wear headphones if you value your hearing. The middle-of-the-road bsnes core uses blargg's accurate DSP, because it's about 3% faster than mine which removes all of blargg's optimizations. There is absolutely no accuracy loss here. bsnes v067.20 that is included should be equal to v067 official. Performance: Code: asnes = 58fps bsnes = 172fps +2.97x csnes = 274fps +1.59x +4.72x The binaries are not profiled, so that's an additional 15% slower from the previous builds. Save states only work on asnes, as I don't know how to serialize blargg's cores yet. The copy_func thing is very confusing to me for some reason. The debugger won't work anywhere. Outside of that, please go ahead and bug test. Once I get the debugger and save states working, I'll build some profiled v1.0 releases for all three, and we can test that for a bit and then release.
2010-10-20 11:20:39 +00:00
#if defined(PROFILE_ASNES)
if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread);
Updated to 20100813 release. byuu says: Since we're now talking about three splits, that's getting a bit out of hand. This WIP combines everything back into one project again. Added the src/fast folder that has all the speed-oriented cores. A slight slowdown to csnes from what it was before, I'm using blargg's accurate DSP. I just don't like the idea of releasing a less accurate DSP core than Snes9X v1.52 has. Plus the fast DSP core doesn't serialize yet. I moved back to snes_spc 0.9.0 because I care more about Tales and Star Ocean than I do about Earthworm Jim 2. So if you try EWJ2 on csnes, expect it to sound like it does on Snes9X. In other words, don't wear headphones if you value your hearing. The middle-of-the-road bsnes core uses blargg's accurate DSP, because it's about 3% faster than mine which removes all of blargg's optimizations. There is absolutely no accuracy loss here. bsnes v067.20 that is included should be equal to v067 official. Performance: Code: asnes = 58fps bsnes = 172fps +2.97x csnes = 274fps +1.59x +4.72x The binaries are not profiled, so that's an additional 15% slower from the previous builds. Save states only work on asnes, as I don't know how to serialize blargg's cores yet. The copy_func thing is very confusing to me for some reason. The debugger won't work anywhere. Outside of that, please go ahead and bug test. Once I get the debugger and save states working, I'll build some profiled v1.0 releases for all three, and we can test that for a bit and then release.
2010-10-20 11:20:39 +00:00
#else
while(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) dsp.run();
#endif
}
void SMP::Enter() { smp.enter(); }
void SMP::enter() {
while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
}
op_step();
}
}
void SMP::op_step() {
(this->*opcode_table[op_readpc()])();
}
void SMP::power() {
//targets not initialized/changed upon reset
t0.target = 0;
t1.target = 0;
t2.target = 0;
reset();
}
void SMP::reset() {
create(Enter, system.apu_frequency());
regs.pc = 0xffc0;
regs.a = 0x00;
regs.x = 0x00;
regs.y = 0x00;
regs.sp = 0xef;
regs.p = 0x02;
for(unsigned i = 0; i < memory::apuram.size(); i++) {
memory::apuram.write(i, 0x00);
}
status.clock_counter = 0;
status.dsp_counter = 0;
status.timer_step = 3;
//$00f0
status.clock_speed = 0;
status.timer_speed = 0;
status.timers_enabled = true;
status.ram_disabled = false;
status.ram_writable = true;
status.timers_disabled = false;
//$00f1
status.iplrom_enabled = true;
//$00f2
status.dsp_addr = 0x00;
//$00f8,$00f9
status.smp_f8 = 0x00;
status.smp_f9 = 0x00;
t0.stage0_ticks = 0;
t1.stage0_ticks = 0;
t2.stage0_ticks = 0;
t0.stage1_ticks = 0;
t1.stage1_ticks = 0;
t2.stage1_ticks = 0;
t0.stage2_ticks = 0;
t1.stage2_ticks = 0;
t2.stage2_ticks = 0;
t0.stage3_ticks = 0;
t1.stage3_ticks = 0;
t2.stage3_ticks = 0;
t0.current_line = 0;
t1.current_line = 0;
t2.current_line = 0;
t0.enabled = false;
t1.enabled = false;
t2.enabled = false;
}
SMP::SMP() {
}
SMP::~SMP() {
}
}