示例#1
0
        private void SimulationThread()
        {
            double delay_time;

            m_disassembler          = new Z80Disassembler();
            m_disassembler.ReadByte = ReadMemory;

            m_stopwatch = new Stopwatch();

            m_instruction_start_pc = TVC.CPU.Registers.PC;
            m_instruction_t_cycle  = 0;

            m_debug_event_timestamp = DateTime.Now;

            delay_time = 0;

            while (m_thread_running)
            {
                // handle execution state change
                switch (m_execution_state_request)
                {
                // change to pause state
                case ExecutionStateRequest.Pause:
                    m_execution_state_request = ExecutionStateRequest.NoChange;
                    m_last_execution_state    = m_execution_state;
                    m_execution_state         = ExecutionState.Paused;
                    m_execution_state_changed_event.Set();
                    break;

                case ExecutionStateRequest.Restore:
                    m_execution_state_request = ExecutionStateRequest.NoChange;
                    m_execution_state         = m_last_execution_state;
                    m_execution_state_changed_event.Set();
                    break;

                // change to running
                case ExecutionStateRequest.Run:
                    m_execution_state_request = ExecutionStateRequest.NoChange;
                    m_execution_state         = ExecutionState.Running;
                    m_execution_state_changed_event.Set();
                    break;

                // full speed run
                case ExecutionStateRequest.RunFullSpeed:
                    m_execution_state_request = ExecutionStateRequest.NoChange;
                    m_execution_state         = ExecutionState.RunningFullSpeed;
                    m_execution_state_changed_event.Set();
                    break;

                // resets computer
                case ExecutionStateRequest.Reset:
                    m_execution_state_request = ExecutionStateRequest.NoChange;
                    TVC.Reset();
                    m_execution_state_changed_event.Set();
                    break;

                // no change
                case ExecutionStateRequest.NoChange:
                    // do nothing
                    break;
                }

                // execute according the execution state
                switch (m_execution_state)
                {
                case ExecutionState.Running:
                {
                    uint ellapsed_tick;

                    //m_stopwatch.Restart();
                    ellapsed_tick = RunOneFrame();
                    GenerateDebugEvent(false);
                    //m_stopwatch.Stop();

                    //delay_time += TVC.CPUTickToMillisec(ellapsed_tick) - m_stopwatch.Elapsed.TotalMilliseconds;

                    m_thread_event.WaitOne(1000);

                    /*
                     *                                        if (delay_time > 0)
                     *                                        {
                     *                                                int delay = (int)Math.Truncate(delay_time);
                     *
                     *                                                m_stopwatch.Restart();
                     *                                                m_thread_event.WaitOne(delay);
                     *                                                m_stopwatch.Stop();
                     *                                                delay_time -= m_stopwatch.Elapsed.TotalMilliseconds;
                     *                                        }
                     *                                        else
                     *                                        {
                     *                                                // execution is behind the schedule -> no delay
                     *                                                m_thread_event.WaitOne(0);
                     *
                     *                                                delay_time = 0;
                     *                                        }
                     */
                }
                break;

                case ExecutionState.RunningFullSpeed:
                    RunOneFrame();
                    GenerateDebugEvent(false);
                    m_thread_event.WaitOne(0);
                    break;

                case ExecutionState.Paused:
                    m_thread_event.WaitOne(1000);
                    break;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Runs simulation for one video frame
        /// </summary>
        private uint RunOneFrame()
        {
            uint current_instruction_t_cycle;
            uint frame_start_cycle = m_cpu_t_cycle;
            bool breakpoint_exit   = false;
            bool frame_finished    = false;

            while (m_thread_running && !breakpoint_exit && !frame_finished)
            {
                m_target_cycle += 200;                   //TODO: calculate from video timing
                TVC.Memory.VideoMemAccessCount = 0;

                frame_finished = TVC.Video.RenderScanline();

                do
                {
                    current_instruction_t_cycle = TVC.CPU.Step();
                    m_cpu_t_cycle         += current_instruction_t_cycle;
                    m_instruction_t_cycle += current_instruction_t_cycle;

                    if (TVC.CPU.InstructionDone)
                    {
                        AddInstructionToExecutionHistory(m_instruction_start_pc, m_instruction_t_cycle);

                        m_instruction_start_pc = TVC.CPU.Registers.PC;
                        m_instruction_t_cycle  = 0;

                        if (TVC.CPU.Registers.PC == BreakpointAddress)
                        {
                            breakpoint_exit   = true;
                            m_execution_state = ExecutionState.Paused;
                        }

                        // do sound interrupt handling
                        TVC.Sound.PeriodicCallback();
                    }

                    // handle pending interrupts
                    if (TVC.Interrupt.IsIntActive())
                    {
                        m_cpu_t_cycle += (uint)TVC.CPU.Int();
                    }

                    // do sound interrupt handling
                    if (TVC.Sound != null)
                    {
                        TVC.Sound.PeriodicCallback();
                    }

                    // handle clock stretching (video memory access)
                    if (TVC.Memory.VideoMemAccessCount > 0)
                    {
                        m_cpu_t_cycle += (uint)(TVC.Memory.VideoMemAccessCount + 1);
                        TVC.Memory.VideoMemAccessCount = 0;
                    }
                } while (((long)m_target_cycle - m_cpu_t_cycle) > 0 && m_thread_running && !breakpoint_exit);

                TVC.PeriodicCallback();
                TVC.Keyboard.Update();

                TVC.Sound.PeriodicCallback();
            }

            if (breakpoint_exit)
            {
                GenerateDebugEvent(true);
            }

            // return frame total cycle
            return(m_cpu_t_cycle - frame_start_cycle);
        }
示例#3
0
        public void Initialize()
        {
            TVC.Initialize();

            DebuggerBreakEvent?.Invoke(TVC);
        }