示例#1
0
        /// <summary>
        ///     Method used to Run the Emulator Task
        ///
        ///     Task will run until the _powerOn value is set to false
        /// </summary>
        private void Run()
        {
            //Frame Timing Stopwatch
            var sw = Stopwatch.StartNew();

            //CPU startup state is always at 4 cycles
            _cpu.Cycles = 4;

            int cpuTicks;

            while (_powerOn)
            {
                //If we're not idling (DMA), tick the CPU
                if (_cpuIdleCycles == 0)
                {
                    cpuTicks = _cpu.Tick();
                }
                else
                {
                    //Otherwise, mark it as an idle cycle and carry on
                    _cpuIdleCycles--;
                    _cpu.Instruction.Cycles = 1;
                    _cpu.Cycles++;
                    cpuTicks = 1;
                }

                //Count how many cycles that instruction took and
                //execute that number of instruction * 3 for the PPU
                //We do ceiling since it's ok for the PPU to overshoot at this point
                for (var i = 0; i < cpuTicks * 3; i++)
                {
                    _ppu.Tick();
                }

                //If the PPU has signaled NMI, reset its status and signal the CPU
                if (_ppu.NMI)
                {
                    _ppu.NMI = false;
                    _cpu.NMI = true;
                }

                //Check to see if there's a frame in the PPU Frame Buffer
                //If there is, let's render it
                if (_ppu.FrameReady)
                {
                    _processFrame(_ppu.FrameBuffer);
                    _ppu.FrameReady = false;

                    //Throttle our frame rate here to the desired rate (if required)
                    switch (_enumEmulatorSpeed)
                    {
                    case enumEmulatorSpeed.Turbo:
                        continue;

                    case enumEmulatorSpeed.Normal when sw.ElapsedMilliseconds < 17:
                        Thread.Sleep((int)(17 - sw.ElapsedMilliseconds));
                        break;

                    case enumEmulatorSpeed.Half when sw.ElapsedMilliseconds < 32:
                        Thread.Sleep((int)(32 - sw.ElapsedMilliseconds));
                        break;
                    }
                    sw.Restart();
                }
            }
        }