Path: blob/master/libsnes/bsnes/snes/smp/timing/timing.cpp
2 views
#ifdef SMP_CPP12void SMP::add_clocks(unsigned clocks) {3step(clocks);4synchronize_dsp();56#if defined(DEBUGGER)7#error -DDEBUGGER SMP runtosave() correctness not checked8synchronize_cpu();9#else10//forcefully sync S-SMP to S-CPU in case chips are not communicating11//sync if S-SMP is more than 24 samples ahead of S-CPU12/*13our new smp design guarantees that there is at most one required synchronize_cpu() per uop,14inside an op_busread() or op_buswrite(). this extra synchronize can cause problems if we15swap out of the SMP at the beginning of a uop with an add_clocks() call when there is an16important op_busread() / op_buswrite() later on. the SMP will need to finish that uop in17order to reach a savable state, but it might never get to do so until it's too late (ie,18scheduler.sync == Scheduler.SynchronizeMode::All). so we remove this call and instead19do catchup sync in the main Enter() loop.20*/21//if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu();22#endif23}2425void SMP::cycle_edge() {26timer0.tick();27timer1.tick();28timer2.tick();2930//TEST register S-SMP speed control31//24 clocks have already been added for this cycle at this point32switch(status.clock_speed) {33case 0: break; //100% speed34case 1: add_clocks(24); break; // 50% speed35case 2: while(true) add_clocks(24); // 0% speed -- locks S-SMP36case 3: add_clocks(24 * 9); break; // 10% speed37}38}3940template<unsigned timer_frequency>41void SMP::Timer<timer_frequency>::tick() {42//stage 0 increment43stage0_ticks += smp.status.timer_step;44if(stage0_ticks < timer_frequency) return;45stage0_ticks -= timer_frequency;4647//stage 1 increment48stage1_ticks ^= 1;49synchronize_stage1();50}5152template<unsigned timer_frequency>53void SMP::Timer<timer_frequency>::synchronize_stage1() {54bool new_line = stage1_ticks;55if(smp.status.timers_enable == false) new_line = false;56if(smp.status.timers_disable == true) new_line = false;5758bool old_line = current_line;59current_line = new_line;60if(old_line != 1 || new_line != 0) return; //only pulse on 1->0 transition6162//stage 2 increment63if(enable == false) return;64if(++stage2_ticks != target) return;6566//stage 3 increment67stage2_ticks = 0;68stage3_ticks++;69}7071#endif727374