| 42 | //**************************************************************************** |
| 43 | |
| 44 | __fi void _vu0run(bool breakOnMbit, bool addCycles, bool sync_only) { |
| 45 | |
| 46 | if (!(VU0.VI[REG_VPU_STAT].UL & 1)) return; |
| 47 | |
| 48 | //VU0 is ahead of the EE and M-Bit is already encountered, so no need to wait for it, just catch up the EE |
| 49 | if ((VU0.flags & VUFLAG_MFLAGSET) && breakOnMbit && (s64)(cpuRegs.cycle - VU0.cycle) <= 0) |
| 50 | { |
| 51 | cpuRegs.cycle = VU0.cycle; |
| 52 | return; |
| 53 | } |
| 54 | |
| 55 | if(!EmuConfig.Cpu.Recompiler.EnableEE) |
| 56 | intUpdateCPUCycles(); |
| 57 | |
| 58 | u64 startcycle = cpuRegs.cycle; |
| 59 | s32 runCycles = 0x7fffffff; |
| 60 | |
| 61 | if (sync_only) |
| 62 | { |
| 63 | runCycles = (s64)(cpuRegs.cycle - VU0.cycle); |
| 64 | |
| 65 | if (runCycles < 0) |
| 66 | return; |
| 67 | } |
| 68 | |
| 69 | do { // Run VU until it finishes or M-Bit |
| 70 | CpuVU0->Execute(runCycles); |
| 71 | } while ((VU0.VI[REG_VPU_STAT].UL & 1) // E-bit Termination |
| 72 | && !sync_only && (!breakOnMbit || (!(VU0.flags & VUFLAG_MFLAGSET) && (s32)(cpuRegs.cycle - VU0.cycle) > 0))); // M-bit Break |
| 73 | |
| 74 | // Add cycles if called from EE's COP2 |
| 75 | if (addCycles) |
| 76 | { |
| 77 | cpuRegs.cycle += (VU0.cycle - startcycle); |
| 78 | CpuVU1->ExecuteBlock(0); // Catch up VU1 as it's likely fallen behind |
| 79 | |
| 80 | if(VU0.VI[REG_VPU_STAT].UL & 1) |
| 81 | cpuSetNextEventDelta(4); |
| 82 | } |
| 83 | } |
| 84 | |
| 85 | void _vu0WaitMicro() { _vu0run(1, 1, 0); } // Runs VU0 Micro Until E-bit or M-Bit End |
| 86 | void _vu0FinishMicro() { _vu0run(0, 1, 0); } // Runs VU0 Micro Until E-Bit End |
no test coverage detected