Example #1
0
        public void Reset()
        {
            bool wasExecuting = IsExecuting;

            // Save context and stop executing if the system is currently running.
            SystemExecutionContext context = null;

            if (wasExecuting)
            {
                context = _currentExecutionContext;
                StopExecution();
            }

            // Now do the actual reset.
            _cp.Reset();
            _iop.Reset();
            _displayController.Reset();
            _ethernetController.Reset();
            _hardDrive.Reset();
            _shugartController.Reset();
            // _scheduler.Reset();

            _cpCycles      = 0;
            _elapsedCycles = 0;

            // Restart execution if we were running before the reset.
            if (wasExecuting)
            {
                StartExecution(context);
            }
        }
Example #2
0
        private void ExecutionWorker(object obj)
        {
            SystemExecutionContext context = (SystemExecutionContext)obj;

            _abortExecution = false;

            while (!_abortExecution)
            {
                try
                {
                    //
                    // We clock the IOP first and let it run an instruction.
                    // This returns the number of clock cycles consumed --
                    // on the 8085's 3Mhz timebase.
                    //
                    // We then execute the corresponding number of CP cycles
                    // (based on a 137ns clock period, or about 7.3Mhz) that would
                    // occur during that period.
                    //
                    int i8085Cycles = _iop.Execute();

                    // This is inexact and that's probably good enough on average.
                    _cpCycles = (int)_cpCyclesPer8085Cycle * i8085Cycles;

                    _cp.ExecuteInstruction(_cpCycles);

                    if (Configuration.ThrottleSpeed)
                    {
                        _elapsedCycles += _cpCycles;

                        if (_elapsedCycles > _cpCyclesPerField)
                        {
                            _elapsedCycles -= _cpCyclesPerField;

                            if (_frameTimer != null)
                            {
                                _frameTimer.WaitForFrame();
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    context.ErrorCallback(e);
                    _abortExecution = true;
                }
            }

            ExecutionStateChanged();
        }
Example #3
0
        public void StartExecution(SystemExecutionContext context)
        {
            StopExecution();

            if (_executionThread == null || !_executionThread.IsAlive)
            {
                if (context.StepCallback8085 != null &&
                    context.StepCallbackCP != null &&
                    context.StepCallbackMesa != null)
                {
                    _executionThread = new Thread(new ParameterizedThreadStart(DebugExecutionWorker));
                }
                else
                {
                    _executionThread = new Thread(new ParameterizedThreadStart(ExecutionWorker));
                }
                _executionThread.Start(context);

                ExecutionStateChanged();

                _currentExecutionContext = context;
            }
        }
Example #4
0
        private void DebugExecutionWorker(object obj)
        {
            SystemExecutionContext context = (SystemExecutionContext)obj;

            _abortExecution = false;
            bool iopAbort = false;

            while (!_abortExecution)
            {
                try
                {
                    //
                    // We clock the IOP first and let it run an instruction.
                    // This returns the number of clock cycles consumed --
                    // on the 8085's 3Mhz timebase.
                    //
                    // We then execute the corresponding number of CP cycles
                    // (based on a 137ns clock period, or about 7.3Mhz) that would
                    // occur during that period.
                    //
                    if (_cpCycles == 0)
                    {
                        if (iopAbort)
                        {
                            //
                            // Out of cycles after an IOP abort, now we actually abort.
                            //
                            _abortExecution = true;
                        }
                        else
                        {
                            int i8085Cycles = _iop.Execute();

                            // This is inexact and that's probably good enough on average.
                            _cpCycles = (int)_cpCyclesPer8085Cycle * i8085Cycles;

                            if (context.StepCallback8085())
                            {
                                //
                                // Set our local iopAbort flag, we still want to continue
                                // to execute the CP and scheduler for as many microcycles as correspond to the
                                // above 8085 instruction's execution time to keep things in sync.
                                //
                                iopAbort = true;
                            }
                        }
                    }

                    _cp.ExecuteInstruction(1);
                    _cpCycles--;
                    _elapsedCycles++;

                    if (context.StepCallbackCP())
                    {
                        //
                        // Break on microinstruction step
                        //
                        _abortExecution = true;
                    }

                    if (_cp.IBDispatch &&
                        context.StepCallbackMesa())
                    {
                        //
                        // Break on macroinstruction step
                        //
                        _abortExecution = true;
                    }
                }
                catch (Exception e)
                {
                    context.ErrorCallback(e);
                    _abortExecution = true;
                }
            }

            _cpCycles = 0;

            ExecutionStateChanged();
        }