public void EmulateCycles(long cycleLimit) { long cycleCounter = cycleLimit; PerformanceTimer.Restart(); while (cycleCounter-- > 0) { CycleTimer.Start(); HandleTimers(); PPU.ProcessCycle(); APU.ProcessCycle(); if (CycleCooldown > 0) { if (ExecOpcode != null) { ExecOpcode.ExecuteTick(); } CycleCooldown--; if (CycleCooldown == 0 && ExecOpcode != null) { if (!HaltBug) { PC += (ushort)ExecOpcode.Length; } else { HaltBug = false; } ExecOpcode = null; } WaitForCycleFinish(CycleTimer, cycleCounter); continue; } if (CheckForInterrupt()) { HandleInterrupt(); WaitForCycleFinish(CycleTimer, cycleCounter); continue; } if (Halted) { if (CycleCooldown == 0) { CycleCooldown += 4; } if (CycleCooldown > 0) { WaitForCycleFinish(CycleTimer, cycleCounter); continue; } } if (EINextInstruction) { EINextInstruction = false; InterruptsEnabled = true; } Opcode opcode = Decoder.DecodeOpcode(this, Memory[PC]); if (logTrace) { LogTrace(opcode); } if (opcode.TickAccurate) { ExecOpcode = opcode; } else { ExecOpcode = null; } if (!opcode.TickAccurate) { opcode.Execute(); if (!HaltBug) { PC += (ushort)opcode.Length; } else { HaltBug = false; } } else { ExecOpcode.ExecuteTick(); } CycleCooldown = opcode.Cycles - 1; WaitForCycleFinish(CycleTimer, cycleCounter); } EndTime = PerformanceTimer.ElapsedTicks; }