public void StepInto() { lock (this) { if ((this.SimulationTask != null) && !this.SimulationTask.IsCompleted) { return; } this.BreakToken = new CancellationTokenSource(); AtmelProcessor.Step(); UpdateCurrentInstruction(); } }
public async Task RunTo(int stopPosition) { lock (this) { if ((this.SimulationTask != null) && !this.SimulationTask.IsCompleted) { return; } this.BreakToken = new CancellationTokenSource(); this.SimulationTask = Task.Run(() => { this.CurrentInstruction = null; AtmelProcessor.StartProfiling(); var timer = new HiPerfTimer(); Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; var audioEnabled = this.AudioEnabled; const double sliceTime = 1.0 / AudioPlayer.AudioSlices; double fpsDuration = 0; double simDuration = 0; timer.Start(); if (audioEnabled) { AudioPlayer.Start(); } while (!this.BreakToken.IsCancellationRequested) { // simulate cycles for one slice var startCycles = AtmelContext.Clock; var endCycles = startCycles + AtmelProcessor.ClockSpeed / AudioPlayer.AudioSlices; while (AtmelContext.Clock < endCycles) { AtmelProcessor.Step(); if (this.Breakpoints[AtmelContext.PC] || (AtmelContext.PC == stopPosition)) { this.BreakToken.Cancel(); break; } #if PROFILE // only do this once-per-instruction in profile build, it's really slow if (this.BreakToken.IsCancellationRequested) { this.BreakToken.Cancel(); break; } #endif } timer.Stop(); var duration = timer.Duration; timer.Restart(); fpsDuration += duration; simDuration += duration; this.TotalCycles += (endCycles - startCycles); if (fpsDuration >= 1.0) { this.CyclesPerSecond = (int)(this.TotalCycles / fpsDuration); this.TotalCycles = 0; fpsDuration = 0; } // if audio is enabled then submit the buffer and wait until it starts playing if (audioEnabled) { AudioPlayer.NextBuffer(); } // otherwise sleep off any left-over time else { var remaining = sliceTime - simDuration; if (remaining >= 0) { Thread.Sleep((int)(1000 * remaining)); } simDuration -= sliceTime; } } if (audioEnabled) { AudioPlayer.Stop(); } UpdateCurrentInstruction(); AtmelProcessor.ReportProfiling(); }); } await this.SimulationTask; }