Пример #1
0
        /// <summary>
        /// Starts the machine in a background thread.
        /// </summary>
        /// <param name="options">Options to start the machine with.</param>
        /// <remarks>
        /// Reports completion when the machine starts executing its cycles. The machine can
        /// go into Paused or Stopped state, if the execution options allow, for example,
        /// when it runs to a predefined breakpoint.
        /// </remarks>
        public void Start(ExecuteCycleOptions options)
        {
            if (VmState == VmState.Running)
            {
                return;
            }

            // --- Prepare the machine to run
            IsFirstStart = VmState == VmState.None || VmState == VmState.Stopped;
            SpectrumVm.DebugInfoProvider?.PrepareBreakpoints();
            if (IsFirstStart)
            {
                SpectrumVm.Reset();
                SpectrumVm.Cpu.StackDebugSupport.ClearStepOutStack();
                SpectrumVm.DebugInfoProvider?.ResetHitCounts();
            }

            // --- Dispose the previous cancellation token, and create a new one
            CancellationTokenSource?.Dispose();
            CancellationTokenSource = new CancellationTokenSource();

            // --- Set up the task that runs the machine
            CompletionTask = new Task(async() =>
            {
                Cancelled            = false;
                ExecutionCycleResult = false;
                try
                {
                    ExecutionCycleResult = SpectrumVm.ExecuteCycle(CancellationTokenSource.Token, options);
                }
                catch (TaskCanceledException)
                {
                    Cancelled = true;
                }
                catch (Exception ex)
                {
                    ExecutionCycleException = ex;
                }

                // --- Conclude the execution task
                await ExecuteOnMainThread(() =>
                {
                    MoveToState(VmState == VmState.Stopping ||
                                VmState == VmState.Stopped ||
                                ExecutionCycleException != null
                            ? VmState.Stopped
                            : VmState.Paused);

                    if (ExecutionCycleException != null)
                    {
                        VmStoppedWithException?.Invoke(this, EventArgs.Empty);
                    }
                });
            });

            MoveToState(VmState.Running);
            CompletionTask.Start();
        }
Пример #2
0
        /// <summary>
        /// Starts the machine in a background thread with the specified options.
        /// </summary>
        /// <remarks>
        /// Reports completion when the machine starts executing its cycles. The machine can
        /// go into Paused or Stopped state, if the execution options allow, for example,
        /// when it runs to a predefined breakpoint.
        /// </remarks>
        public void StartWithOptions(ExecuteCycleOptions options)
        {
            if (MachineState == VmState.Running)
            {
                return;
            }

            // --- Prepare the machine to run
            IsFirstStart = MachineState == VmState.None || MachineState == VmState.Stopped;
            SpectrumVm.DebugInfoProvider?.PrepareBreakpoints();
            MachineState = VmState.Starting;
            if (IsFirstStart)
            {
                SpectrumVm.Reset();
                SpectrumVm.Cpu.StackDebugSupport.Reset();
                SpectrumVm.DebugInfoProvider?.ResetHitCounts();
                CpuFrameCount    = 0;
                RenderFrameCount = 0;
            }

            // --- Dispose the previous cancellation token, and create a new one
            _cancellationTokenSource?.Dispose();
            _cancellationTokenSource = new CancellationTokenSource();

            // --- Set up the task that runs the machine
            MachineState = VmState.Running;
            try
            {
                _completionTask = StartAndRun(_cancellationTokenSource.Token, options);
                _completionTask.GetAwaiter().OnCompleted(async() =>
                {
                    await WaitForPause();
                });
            }
            catch (TaskCanceledException)
            {
                ExecutionCompletionReason = ExecutionCompletionReason.Cancelled;
            }
            catch (Exception ex)
            {
                ExceptionRaised?.Invoke(this, new VmExceptionArgs(ex));
            }
        }
Пример #3
0
        /// <summary>
        /// Builds the machine that can be started
        /// </summary>
        protected virtual void BuildMachine()
        {
            if (SpectrumVm == null)
            {
                MoveToState(VmState.BuildingMachine);

                if (StartupConfiguration == null)
                {
                    throw new InvalidOperationException("You must provide a startup configuration for " +
                                                        "the virtual machine, it cannot be null");
                }

                // --- Create the machine on first start
                SpectrumVm = new Spectrum48(StartupConfiguration.DeviceData, this);
                SpectrumVm.ScreenDevice.FrameCompleted +=
                    (s, e) => VmScreenRefreshed?.Invoke(s,
                                                        new VmScreenRefreshedEventArgs(SpectrumVm.ScreenDevice.GetPixelBuffer()));
            }

            // --- We either provider out DebugInfoProvider, or use
            // --- the default one
            if (StartupConfiguration.DebugInfoProvider == null)
            {
                StartupConfiguration.DebugInfoProvider = SpectrumVm.DebugInfoProvider;
            }
            else
            {
                SpectrumVm.DebugInfoProvider = StartupConfiguration.DebugInfoProvider;
            }
            // --- Set up stack debug support
            if (StartupConfiguration.StackDebugSupport != null)
            {
                SpectrumVm.Cpu.StackDebugSupport = StartupConfiguration.StackDebugSupport;
                StartupConfiguration.StackDebugSupport.Reset();
            }

            // --- At this point we have a Spectrum VM.
            // --- Let's reset it
            SpectrumVm.Reset();
        }