Ejemplo n.º 1
0
        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
                    }
                }
            }
        }