private void Run() { ArrayList cleanInputBuf = new ArrayList(); ArrayList inputBuf = new ArrayList(); Task tsk = null; ExternalInputEvent evt = default(ExternalInputEvent); while (true) { // Detect the end of the simulation run if (nextTime == STOPPING) { nextTime = pq.MinPriority(); break; } if (pendingInput.Count > 0) { // Fetch pending input events inputBuf = pendingInput; pendingInput = cleanInputBuf; } else if (nextTime <= mCurrentTime) { // Fetch the next pending task tsk = NextTask(); if (ReferenceEquals(tsk, null)) { continue; // This task was canceled, go round again } inputBuf.Clear(); } else { tsk = null; } if (inputBuf.Count > 0) { // Process pending input events for (int i = 0; i <= inputBuf.Count - 1; i++) { evt = (ExternalInputEvent)(inputBuf[i]); evt.TimeStamp = mCurrentTime; evt.Handler.HandleInput(evt); } inputBuf.Clear(); cleanInputBuf = inputBuf; } else if (tsk != null) { // Run the first pending task tsk.Start(); } else { // Run the CPU simulation for a bit (maxRunCycl) try { mCPU.RunEmulation(); } catch (Exception ex) { X8086.Notify("Shit happens at {0}:{1}: {2}", X8086.NotificationReasons.Fck, mCPU.Registers.CS.ToString("X4"), mCPU.Registers.IP.ToString("X4"), ex.Message); mCPU.RaiseException($"Scheduler Main Loop Error: {ex.Message}"); } if (mCPU.IsHalted) { SkipToNextEvent(); // The CPU is halted, skip immediately to the next event } } } }