/// <summary>
        /// Waits while the Spectrum virtual machine starts and reaches its termination point
        /// </summary>
        /// <returns>True, if started within timeout; otherwise, false</returns>
        private async Task <bool> WaitStart()
        {
            const int TIME_OUT_IN_SECONDS = 5;
            var       counter             = 0;

            while (Package.MachineViewModel.VmState != VmState.Paused && counter < TIME_OUT_IN_SECONDS * 10)
            {
                await Task.Delay(100);

                counter++;
            }
            if (Package.MachineViewModel.VmState != VmState.Paused)
            {
                var pane    = OutputWindow.GetPane <SpectrumVmOutputPane>();
                var message = $"The ZX Spectrum virtual machine did not start within {TIME_OUT_IN_SECONDS} seconds.";
                pane.WriteLine(message);
                VsxDialogs.Show(message, "Unexpected issue", MessageBoxButton.OK, VsxMessageBoxIcon.Error);
                Package.MachineViewModel.StopVm();
                return(false);
            }
            return(true);
        }
示例#2
0
        /// <summary>
        /// Compiles the file with the specified file name
        /// </summary>
        /// <param name="filename">Test file to compile</param>
        /// <param name="createLog">Signs if build log should be created</param>
        /// <returns>Test plan</returns>
        public TestFilePlan CompileFile(string filename, bool createLog = true)
        {
            var start = DateTime.Now;
            var pane  = OutputWindow.GetPane <Z80BuildOutputPane>();

            if (createLog)
            {
                pane.WriteLine("Z80 Test Compiler");
                pane.WriteLine($"Compiling {filename}");
            }
            var compiler = new Z80TestCompiler
            {
                DefaultSourceFolder = Path.GetDirectoryName(filename)
            };

            if (createLog)
            {
                var duration = (DateTime.Now - start).TotalMilliseconds;
                pane.WriteLine($"Compile time: {duration}ms");
            }
            return(compiler.CompileFile(filename));
        }
示例#3
0
        /// <summary>
        /// Loads the specified .vmstate file
        /// </summary>
        /// <param name="stateFile">Full name of the .vmstate file</param>
        public void LoadVmStateFile(string stateFile)
        {
            var state = File.ReadAllText(stateFile);

            try
            {
                Package.MachineViewModel.SpectrumVm.SetVmState(state, Package.CodeDiscoverySolution.CurrentProject.ModelName);
                Package.MachineViewModel.SpectrumVm.BeeperDevice.Reset();
                Package.MachineViewModel.SpectrumVm.BeeperProvider.Reset();

                var pane = OutputWindow.GetPane <SpectrumVmOutputPane>();
                pane.WriteLine($"Forcing Paused state from {Package.MachineViewModel.VmState}");
                Package.MachineViewModel.ForcePauseVmAfterStateRestore();
            }
            catch (InvalidVmStateException e)
            {
                VsxDialogs.Show(e.OriginalMessage, "Error loading virtual machine state");
            }
            catch (Exception e)
            {
                VsxDialogs.Show($"Unexpected error: {e.Message}", "Error loading virtual machine state");
            }
        }
示例#4
0
        /// <summary>
        /// Compiles the code.
        /// </summary>
        /// <returns>True, if compilation successful; otherwise, false</returns>
        /// <param name="createLog">Signs if build log should be created</param>
        public TestProjectPlan CompileAllFiles(bool createLog = true)
        {
            Package.ErrorList.Clear();
            var result    = new TestProjectPlan();
            var testFiles = Package.CodeDiscoverySolution.CurrentProject.Z80TestProjectItems;

            if (testFiles.Count == 0)
            {
                return(result);
            }

            var testManager = Package.TestManager;
            var start       = DateTime.Now;
            var pane        = OutputWindow.GetPane <Z80BuildOutputPane>();

            if (createLog)
            {
                pane.WriteLine("Z80 Test Compiler");
            }
            foreach (var file in testFiles)
            {
                var filename = file.Filename;
                if (createLog)
                {
                    pane.WriteLine($"Compiling {filename}");
                }
                var testPlan = testManager.CompileFile(filename);
                result.Add(testPlan);
            }

            if (createLog)
            {
                var duration = (DateTime.Now - start).TotalMilliseconds;
                pane.WriteLine($"Compile time: {duration}ms");
            }
            return(result);
        }
示例#5
0
        /// <summary>
        /// Stops the Spectrum VM, displays confirmation, if required
        /// </summary>
        /// <returns>Tru, if start confirmed; otherwise, false</returns>
        public async Task <bool> StopSpectrumVm(bool needConfirm)
        {
            var vm           = Package.MachineViewModel;
            var machineState = vm.VmState;

            if (machineState == VmState.Running || machineState == VmState.Paused)
            {
                if (needConfirm)
                {
                    var answer = VsxDialogs.Show("Are you sure, you want to restart " +
                                                 "the ZX Spectrum virtual machine?",
                                                 "The ZX Spectum virtual machine is running",
                                                 MessageBoxButton.YesNo, VsxMessageBoxIcon.Question, 1);
                    if (answer == VsxDialogResult.No)
                    {
                        return(false);
                    }
                }

                // --- Stop the machine and allow 50ms to stop.
                Package.MachineViewModel.StopVm();
                await Package.MachineViewModel.MachineController.CompletionTask;

                if (vm.VmState == VmState.Stopped)
                {
                    return(true);
                }

                const string MESSAGE = "The ZX Spectrum virtual machine did not stop.";
                var          pane    = OutputWindow.GetPane <SpectrumVmOutputPane>();
                pane.WriteLine(MESSAGE);
                VsxDialogs.Show(MESSAGE, "Unexpected issue",
                                MessageBoxButton.OK, VsxMessageBoxIcon.Error);
                return(false);
            }
            return(true);
        }
示例#6
0
        /// <summary>
        /// Compiles the Z80 code file
        /// </summary>
        protected override async Task ExecuteAsync()
        {
            // --- Prepare the appropriate file to compile/run
            GetCodeItem(out var hierarchy, out var itemId);

            // --- Step #1: Compile the code
            if (!CompileCode(hierarchy, itemId))
            {
                return;
            }

            // --- Step #2: Check machine compatibility
            var modelName = SpectNetPackage.Default.CodeDiscoverySolution?.CurrentProject?.ModelName;
            SpectrumModelType modelType;

            if (Output.ModelType == null)
            {
                switch (modelName)
                {
                case SpectrumModels.ZX_SPECTRUM_48:
                    modelType = SpectrumModelType.Spectrum48;
                    break;

                case SpectrumModels.ZX_SPECTRUM_128:
                    modelType = SpectrumModelType.Spectrum128;
                    break;

                case SpectrumModels.ZX_SPECTRUM_P3_E:
                    modelType = SpectrumModelType.SpectrumP3;
                    break;

                case SpectrumModels.ZX_SPECTRUM_NEXT:
                    modelType = SpectrumModelType.Next;
                    break;

                default:
                    modelType = SpectrumModelType.Spectrum48;
                    break;
                }
            }
            else
            {
                modelType = Output.ModelType.Value;
            }
            if (!SpectNetPackage.IsCurrentModelCompatibleWith(modelType))
            {
                VsxDialogs.Show("The model type defined in the code is not compatible with the " +
                                "Spectum virtual machine of this project.",
                                "Cannot run code.");
                return;
            }

            // --- Step #3: Check for zero code length
            if (Output.Segments.Sum(s => s.EmittedCode.Count) == 0)
            {
                VsxDialogs.Show("The lenght of the compiled code is 0, " +
                                "so there is no code to inject into the virtual machine and run.",
                                "No code to run.");
                return;
            }

            // --- Step #4: Check non-zero displacements
            var options = Package.Options;

            if (Output.Segments.Any(s => (s.Displacement ?? 0) != 0) && options.ConfirmNonZeroDisplacement)
            {
                var answer = VsxDialogs.Show("The compiled code contains non-zero displacement" +
                                             "value, so the displaced code may fail. Are you sure you want to run the code?",
                                             "Non-zero displacement found",
                                             MessageBoxButton.YesNo, VsxMessageBoxIcon.Question, 1);
                if (answer == VsxDialogResult.No)
                {
                    return;
                }
            }

            // --- Step #5: Stop the virtual machine if required
            await SwitchToMainThreadAsync();

            Package.ShowToolWindow <SpectrumEmulatorToolWindow>();
            var pane    = OutputWindow.GetPane <SpectrumVmOutputPane>();
            var vm      = Package.MachineViewModel;
            var stopped = await Package.CodeManager.StopSpectrumVm(options.ConfirmMachineRestart);

            if (!stopped)
            {
                return;
            }

            // --- Step #6: Start the virtual machine so that later we can load the program
            pane.WriteLine("Starting the virtual machine in code injection mode.");

            // --- Use specific startup for each model.
            bool started = true;

            try
            {
                switch (modelName)
                {
                case SpectrumModels.ZX_SPECTRUM_48:
                    await Package.StateFileManager.SetSpectrum48StartupState();

                    break;

                case SpectrumModels.ZX_SPECTRUM_128:
                    if (modelType == SpectrumModelType.Spectrum48)
                    {
                        await Package.StateFileManager.SetSpectrum128In48StartupState();
                    }
                    else
                    {
                        await Package.StateFileManager.SetSpectrum128In128StartupState();
                    }
                    break;

                case SpectrumModels.ZX_SPECTRUM_P3_E:
                    if (modelType == SpectrumModelType.Spectrum48)
                    {
                        await Package.StateFileManager.SetSpectrumP3In48StartupState();
                    }
                    else
                    {
                        await Package.StateFileManager.SetSpectrumP3InP3StartupState();
                    }
                    break;

                case SpectrumModels.ZX_SPECTRUM_NEXT:
                    // --- Implement later
                    return;

                default:
                    // --- Implement later
                    return;
                }
            }
            catch (Exception)
            {
                started = false;
            }
            if (!started)
            {
                return;
            }

            // --- Step #7: Inject the code into the memory, and force
            // --- new disassembly
            pane.WriteLine("Injecting code into the Spectrum virtual machine.");
            Package.CodeManager.InjectCodeIntoVm(Output);

            // --- Step #8: Jump to execute the code
            var continuationPoint = GetContinuationAddress();

            if (continuationPoint.HasValue)
            {
                vm.SpectrumVm.Cpu.Registers.PC = continuationPoint.Value;
                pane.WriteLine($"Resuming code execution at address {vm.SpectrumVm.Cpu.Registers.PC:X4}.");
            }
            ResumeVm();
        }
示例#7
0
        public static void Report(Exception ex)
        {
            var pane = OutputWindow.GetPane <SpectNetIdeOutputPane>();

            pane.WriteLine($"Exception occured in SpectNetIde: {ex.Message}\nFull message: ${ex.ToString()}");
        }
        /// <summary>
        /// Overrid this method to handle vm state changes within the controller
        /// </summary>
        /// <param name="oldState">Old VM state</param>
        /// <param name="newState">New VM state</param>
        protected override void OnVmStateChanged(VmState oldState, VmState newState)
        {
            var pane = OutputWindow.GetPane <SpectrumVmOutputPane>();

            pane.WriteLine($"Machine state changed: {oldState} --> {newState}.");
        }
示例#9
0
        /// <summary>
        /// Responds to the event when the Z80 assembler releases a message
        /// </summary>
        private void OnAssemblerMessage(object sender, AssemblerMessageArgs e)
        {
            var pane = OutputWindow.GetPane <Z80AssemblerOutputPane>();

            pane.WriteLine(e.Message);
        }
示例#10
0
        /// <summary>
        /// Compiles the Z80 code file
        /// </summary>
        protected override async Task ExecuteAsync()
        {
            // --- Prepare the appropriate file to compile/run
            CodeInjected = false;

            // --- Step #1: Compile the code
            var success = await Task.Run(() => CompileCode());

            if (!success)
            {
                return;
            }

            // --- Step #2: Check machine compatibility
            var modelName = SpectNetPackage.Default.Solution.ActiveProject?.ModelName;
            SpectrumModelType modelType;

            if (Output.ModelType == null)
            {
                switch (modelName)
                {
                case SpectrumModels.ZX_SPECTRUM_48:
                    modelType = SpectrumModelType.Spectrum48;
                    break;

                case SpectrumModels.ZX_SPECTRUM_128:
                    modelType = SpectrumModelType.Spectrum128;
                    break;

                case SpectrumModels.ZX_SPECTRUM_P3_E:
                    modelType = SpectrumModelType.SpectrumP3;
                    break;

                case SpectrumModels.ZX_SPECTRUM_NEXT:
                    modelType = SpectrumModelType.Next;
                    break;

                default:
                    modelType = SpectrumModelType.Spectrum48;
                    break;
                }
            }
            else
            {
                modelType = Output.ModelType.Value;
            }

            // --- We may display dialogs, so we go back to the main thread
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            if (!SpectrumModels.IsModelCompatibleWith(modelName, modelType))
            {
                VsxDialogs.Show("The model type defined in the code is not compatible with the " +
                                "Spectum virtual machine of this project.",
                                "Cannot run code.");
                return;
            }

            // --- Step #3: Check for zero code length
            if (Output.Segments.Sum(s => s.EmittedCode.Count) == 0)
            {
                VsxDialogs.Show("The lenght of the compiled code is 0, " +
                                "so there is no code to inject into the virtual machine and run.",
                                "No code to run.");
                return;
            }

            // --- Step #4: Check non-zero displacements
            var options = HostPackage.Options;

            if (Output.Segments.Any(s => (s.Displacement ?? 0) != 0) && options.ConfirmNonZeroDisplacement)
            {
                var answer = VsxDialogs.Show("The compiled code contains non-zero displacement" +
                                             "value, so the displaced code may fail. Are you sure you want to run the code?",
                                             "Non-zero displacement found",
                                             MessageBoxButton.YesNo, VsxMessageBoxIcon.Question, 1);
                if (answer == VsxDialogResult.No)
                {
                    return;
                }
            }

            var vm   = HostPackage.EmulatorViewModel;
            var pane = OutputWindow.GetPane <SpectrumVmOutputPane>();

            HostPackage.ShowToolWindow <SpectrumEmulatorToolWindow>();

            // --- Step #5: Prepare the machine to be in the appropriate mode
            if (IsInInjectMode)
            {
                if (vm.MachineState == VmState.Running ||
                    vm.MachineState != VmState.Paused && vm.MachineState != VmState.Stopped && vm.MachineState != VmState.None)
                {
                    VsxDialogs.Show("To inject the code into the virtual machine, please pause it first.",
                                    "The virtual machine is running");
                    return;
                }
            }
            else
            {
                var stopped = await SpectrumVmManager.StopSpectrumVmAsync(options.ConfirmMachineRestart);

                if (!stopped)
                {
                    return;
                }
            }

            // --- Step #6: Start the virtual machine and run it to the injection point
            if (vm.MachineState == VmState.Stopped || vm.MachineState == VmState.None)
            {
                await pane.WriteLineAsync("Starting the virtual machine in code injection mode.");

                // --- Use specific startup for each model.
                var started = true;
                try
                {
                    switch (modelName)
                    {
                    case SpectrumModels.ZX_SPECTRUM_48:
                        await VmStateFileManager.SetSpectrum48StartupState();

                        break;

                    case SpectrumModels.ZX_SPECTRUM_128:
                        if (modelType == SpectrumModelType.Spectrum48)
                        {
                            await VmStateFileManager.SetSpectrum128In48StartupState();
                        }
                        else
                        {
                            await VmStateFileManager.SetSpectrum128In128StartupState();
                        }
                        break;

                    case SpectrumModels.ZX_SPECTRUM_P3_E:
                        if (modelType == SpectrumModelType.Spectrum48)
                        {
                            await VmStateFileManager.SetSpectrumP3In48StartupState();
                        }
                        else
                        {
                            await VmStateFileManager.SetSpectrumP3InP3StartupState();
                        }
                        break;

                    case SpectrumModels.ZX_SPECTRUM_NEXT:
                        // --- Implement later
                        return;

                    default:
                        // --- Implement later
                        return;
                    }
                }
                catch (Exception)
                {
                    started = false;
                }
                if (!started)
                {
                    return;
                }
            }

            // --- Step #7: Inject the code into the memory, and force
            // --- new disassembly
            await pane.WriteLineAsync("Injecting code into the Spectrum virtual machine.");

            HostPackage.CodeManager.InjectCodeIntoVm(Output);
            CodeInjected = true;

            // --- Step #8: Jump to execute the code
            var continuationPoint = GetContinuationAddress();

            if (continuationPoint.HasValue)
            {
                vm.Machine.SpectrumVm.Cpu.Registers.PC = continuationPoint.Value;
                await pane.WriteLineAsync($"Resuming code execution at address {vm.Machine.SpectrumVm.Cpu.Registers.PC:X4}.");
            }
            vm.MemViewPoint    = (ushort)MemoryStartAddress;
            vm.DisAssViewPoint = (ushort)DisassemblyStartAddress;
            vm.StackDebugSupport.ClearStepOutStack();

            GetAffectedItem(out var hierarchy, out var itemId);
            var ext = string.Empty;

            if (hierarchy is IVsProject project)
            {
                project.GetMkDocument(itemId, out var itemFullPath);
                ext = Path.GetExtension(itemFullPath) ?? string.Empty;
            }

            if (ext.ToLower() == ".zxbas")
            {
                // --- Push the MAIN_EXECUTION loop address to the stack
                var memDevice = vm.Machine.SpectrumVm.MemoryDevice;
                var spValue   = vm.Machine.SpectrumVm.Cpu.Registers.SP;
                var mainExec  = VmStateFileManager.SP48_MAIN_EXEC_ADDR;
                memDevice.Write((ushort)(spValue - 1), (byte)(mainExec >> 8));
                memDevice.Write((ushort)(spValue - 2), (byte)mainExec);
                vm.Machine.SpectrumVm.Cpu.Registers.SP -= 2;
            }
            ResumeVm();
        }
示例#11
0
        /// <summary>
        /// Logs a message
        /// </summary>
        /// <param name="message">Message to log</param>
        public static void LogMessage(string message)
        {
            var pane = OutputWindow.GetPane <SpectrumVmOutputPane>();

            pane.WriteLine(message);
        }
        /// <summary>
        /// Compiles the Z80 code file
        /// </summary>
        protected override async Task ExecuteAsync()
        {
            GetItem(out var hierarchy, out var itemId);
            if (hierarchy == null)
            {
                return;
            }

            var codeManager = Package.CodeManager;
            var options     = Package.Options;

            // --- Step #1: Compile
            var start = DateTime.Now;
            var pane  = OutputWindow.GetPane <Z80OutputPane>();

            pane.WriteLine("Z80 Assembler");
            _output = codeManager.Compile(hierarchy, itemId);
            var duration = (DateTime.Now - start).TotalMilliseconds;

            pane.WriteLine($"Compile time: {duration}ms");

            if (_output.ErrorCount != 0)
            {
                // --- Compilation completed with errors
                return;
            }
            if (_output.Segments.Sum(s => s.EmittedCode.Count) == 0)
            {
                VsxDialogs.Show("The lenght of the compiled code is 0, " +
                                "so there is no code to inject into the virtual machine and run.",
                                "No code to run.");
                return;
            }

            // --- Step #2: Check non-zero displacements
            if (_output.Segments.Any(s => (s.Displacement ?? 0) != 0) && options.ConfirmNonZeroDisplacement)
            {
                var answer = VsxDialogs.Show("The compiled code contains non-zero displacement" +
                                             "value, so the displaced code may fail. Are you sure you want to run the code?",
                                             "Non-zero displacement found",
                                             MessageBoxButton.YesNo, VsxMessageBoxIcon.Question, 1);
                if (answer == VsxDialogResult.No)
                {
                    return;
                }
            }

            // --- Step #3: Stop the virtual machine if required
            await SwitchToMainThreadAsync();

            Package.ShowToolWindow <SpectrumEmulatorToolWindow>();
            var vm           = Package.MachineViewModel;
            var machineState = vm.VmState;

            if ((machineState == VmState.Running || machineState == VmState.Paused))
            {
                if (options.ConfirmMachineRestart)
                {
                    var answer = VsxDialogs.Show("Are you sure, you want to restart " +
                                                 "the ZX Spectrum virtual machine?",
                                                 "The ZX Spectum virtual machine is running",
                                                 MessageBoxButton.YesNo, VsxMessageBoxIcon.Question, 1);
                    if (answer == VsxDialogResult.No)
                    {
                        return;
                    }
                }

                // --- Stop the machine and allow 3 frames' time to stop.
                Package.MachineViewModel.StopVmCommand.Execute(null);
                await Task.Delay(60);

                if (vm.VmState != VmState.Stopped)
                {
                    VsxDialogs.Show("The ZX Spectrum virtual machine did not stop.",
                                    "Unexpected issue", MessageBoxButton.OK, VsxMessageBoxIcon.Error);
                    return;
                }
            }

            // --- Step #4: Start the virtual machine so that later we can load the program
            vm.StartVmWithCodeCommand.Execute(null);

            const int timeOutInSeconds = 5;
            var       counter          = 0;

            while (vm.VmState != VmState.Paused && counter < timeOutInSeconds * 10)
            {
                await Task.Delay(100);

                counter++;
            }
            if (vm.VmState != VmState.Paused)
            {
                VsxDialogs.Show($"The ZX Spectrum virtual machine did not start within {timeOutInSeconds} seconds.",
                                "Unexpected issue", MessageBoxButton.OK, VsxMessageBoxIcon.Error);
                vm.StopVmCommand.Execute(null);
            }

            // --- Step #5: Inject the code into the memory
            codeManager.InjectCodeIntoVm(_output);

            // --- Step #6: Jump to execute the code
            vm.SpectrumVm.Cpu.Registers.PC = _output.EntryAddress ?? _output.Segments[0].StartAddress;
            ResumeVm();
        }
示例#13
0
        /// <summary>
        /// Compiles the Z80 code file
        /// </summary>
        protected override async Task ExecuteAsync()
        {
            // --- Prepare the appropriate file to compile/run
            GetCodeItem(out var hierarchy, out var itemId);

            // --- Step #1: Compile the code
            if (!CompileCode(hierarchy, itemId))
            {
                return;
            }

            // --- Step #2: Check machine compatibility
            var modelName = SpectNetPackage.Default.CodeDiscoverySolution?.CurrentProject?.ModelName;
            SpectrumModelType modelType;

            if (Output.ModelType == null)
            {
                switch (modelName)
                {
                case SpectrumModels.ZX_SPECTRUM_48:
                    modelType = SpectrumModelType.Spectrum48;
                    break;

                case SpectrumModels.ZX_SPECTRUM_128:
                    modelType = SpectrumModelType.Spectrum128;
                    break;

                case SpectrumModels.ZX_SPECTRUM_P3:
                    modelType = SpectrumModelType.SpectrumP3;
                    break;

                case SpectrumModels.ZX_SPECTRUM_NEXT:
                    modelType = SpectrumModelType.Next;
                    break;

                default:
                    modelType = SpectrumModelType.Spectrum48;
                    break;
                }
            }
            else
            {
                modelType = Output.ModelType.Value;
            }
            if (!SpectNetPackage.IsCurrentModelCompatibleWith(modelType))
            {
                VsxDialogs.Show("The model type defined in the code is not compatible with the " +
                                "Spectum virtual machine of this project.",
                                "Cannot run code.");
                return;
            }

            // --- Step #3: Check for zero code length
            if (Output.Segments.Sum(s => s.EmittedCode.Count) == 0)
            {
                VsxDialogs.Show("The lenght of the compiled code is 0, " +
                                "so there is no code to inject into the virtual machine and run.",
                                "No code to run.");
                return;
            }

            // --- Step #4: Check non-zero displacements
            var options = Package.Options;

            if (Output.Segments.Any(s => (s.Displacement ?? 0) != 0) && options.ConfirmNonZeroDisplacement)
            {
                var answer = VsxDialogs.Show("The compiled code contains non-zero displacement" +
                                             "value, so the displaced code may fail. Are you sure you want to run the code?",
                                             "Non-zero displacement found",
                                             MessageBoxButton.YesNo, VsxMessageBoxIcon.Question, 1);
                if (answer == VsxDialogResult.No)
                {
                    return;
                }
            }

            // --- Step #5: Stop the virtual machine if required
            await SwitchToMainThreadAsync();

            Package.ShowToolWindow <SpectrumEmulatorToolWindow>();
            var pane         = OutputWindow.GetPane <SpectrumVmOutputPane>();
            var vm           = Package.MachineViewModel;
            var machineState = vm.VmState;

            if ((machineState == VmState.Running || machineState == VmState.Paused))
            {
                if (options.ConfirmMachineRestart)
                {
                    var answer = VsxDialogs.Show("Are you sure, you want to restart " +
                                                 "the ZX Spectrum virtual machine?",
                                                 "The ZX Spectum virtual machine is running",
                                                 MessageBoxButton.YesNo, VsxMessageBoxIcon.Question, 1);
                    if (answer == VsxDialogResult.No)
                    {
                        return;
                    }
                }

                // --- Stop the machine and allow 50ms to stop.
                Package.MachineViewModel.StopVm();
                await Task.Delay(50);

                if (vm.VmState != VmState.Stopped)
                {
                    const string MESSAGE = "The ZX Spectrum virtual machine did not stop.";
                    pane.WriteLine(MESSAGE);
                    VsxDialogs.Show(MESSAGE, "Unexpected issue",
                                    MessageBoxButton.OK, VsxMessageBoxIcon.Error);
                    return;
                }
            }

            // --- Step #6: Start the virtual machine so that later we can load the program
            pane.WriteLine("Starting the virtual machine in code injection mode.");

            // --- Use specific startup for each model.
            switch (modelName)
            {
            case SpectrumModels.ZX_SPECTRUM_48:
                // --- Run in ZX Spectrum 48K mode
                vm.RestartVmAndRunToTerminationPoint(0, SP48_MAIN_EXEC_ADDR);
                if (!await WaitStart())
                {
                    return;
                }
                break;

            case SpectrumModels.ZX_SPECTRUM_128:
                // --- Wait while the main menu appears
                vm.RestartVmAndRunToTerminationPoint(0, SP128_MAIN_WAITING_LOOP);
                if (!await WaitStart())
                {
                    return;
                }

                if (modelType == SpectrumModelType.Spectrum48)
                {
                    vm.RunVmToTerminationPoint(1, SP48_MAIN_EXEC_ADDR);

                    // --- Move to Spectrum 48 mode
                    QueueKeyStroke(SpectrumKeyCode.N6, SpectrumKeyCode.CShift);
                    await Task.Delay(WAIT_FOR_MENU_KEY);

                    QueueKeyStroke(SpectrumKeyCode.N6, SpectrumKeyCode.CShift);
                    await Task.Delay(WAIT_FOR_MENU_KEY);

                    QueueKeyStroke(SpectrumKeyCode.N6, SpectrumKeyCode.CShift);
                    await Task.Delay(WAIT_FOR_MENU_KEY);

                    QueueKeyStroke(SpectrumKeyCode.Enter);
                    if (!await WaitStart())
                    {
                        return;
                    }
                }
                else
                {
                    vm.RunVmToTerminationPoint(0, SP128_RETURN_TO_EDITOR);
                    // --- Move to Spectrum 128 mode
                    QueueKeyStroke(SpectrumKeyCode.N6, SpectrumKeyCode.CShift);
                    await Task.Delay(WAIT_FOR_MENU_KEY);

                    QueueKeyStroke(SpectrumKeyCode.Enter);
                    if (!await WaitStart())
                    {
                        return;
                    }
                }
                break;

            case SpectrumModels.ZX_SPECTRUM_P3:
                // --- Implement later
                return;

            case SpectrumModels.ZX_SPECTRUM_NEXT:
                // --- Implement later
                return;

            default:
                // --- Implement later
                return;
            }

            // --- Step #7: Inject the code into the memory, and force
            // --- new disassembly
            pane.WriteLine("Injecting code into the Spectrum virtual machine.");
            Package.CodeManager.InjectCodeIntoVm(Output);

            // --- Step #8: Jump to execute the code
            var continuationPoint = GetContinuationAddress();

            if (continuationPoint.HasValue)
            {
                vm.SpectrumVm.Cpu.Registers.PC = continuationPoint.Value;
                pane.WriteLine($"Resuming code execution at address {vm.SpectrumVm.Cpu.Registers.PC:X4}.");
            }
            ResumeVm();
        }
示例#14
0
        /// <summary>
        /// Logs a message
        /// </summary>
        /// <param name="message">Message to log</param>
        protected override void LogMessage(string message)
        {
            var pane = OutputWindow.GetPane <SpectrumVmOutputPane>();

            pane.WriteLine(message);
        }
示例#15
0
        /// <summary>
        /// Displays the TRACE pragma messages of the compiler
        /// </summary>
        private static void DisplayTraceMessage(object sender, AssemblerMessageArgs e)
        {
            var pane = OutputWindow.GetPane <Z80BuildOutputPane>();

            pane.WriteLine($"TRACE: {e.Message}");
        }