Exemplo n.º 1
0
        /// <summary>
        /// Exports the list to the specified file
        /// </summary>
        /// <param name="filename"></param>
        public void ExportToFile(string filename)
        {
            var listing = new StringBuilder(4096);

            foreach (var line in ProgramLines)
            {
                listing.Append(line.LineNo);
                listing.Append(" ");
                listing.AppendLine(line.Text);
            }
            try
            {
                var dirName = Path.GetDirectoryName(filename);
                if (!string.IsNullOrEmpty(dirName) && !Directory.Exists(dirName))
                {
                    Directory.CreateDirectory(dirName);
                }
                File.WriteAllText(filename, listing.ToString());
            }
            catch (Exception ex)
            {
                VsxDialogs.Show($"Error while exporting to file {filename}: {ex.Message}",
                                "Export BASIC listing error.", MessageBoxButton.OK, VsxMessageBoxIcon.Error);
                return;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Stops the Spectrum VM, displays confirmation, if required
        /// </summary>
        /// <returns>Tru, if start confirmed; otherwise, false</returns>
        public static async Task<bool> StopSpectrumVmAsync(bool needConfirm)
        {
            var vm = SpectNetPackage.Default.EmulatorViewModel;
            var machineState = vm.MachineState;
            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 Spectrum virtual machine is running",
                        MessageBoxButton.YesNo, VsxMessageBoxIcon.Question, 1);
                    if (answer == VsxDialogResult.No)
                    {
                        return false;
                    }
                }

                // --- Stop the machine and allow 50ms to stop.
                await vm.Machine.Stop();
                if (vm.MachineState == VmState.Stopped) return true;

                const string MESSAGE = "The ZX Spectrum virtual machine did not stop.";
                var pane = OutputWindow.GetPane<SpectrumVmOutputPane>();
                await pane.WriteLineAsync(MESSAGE);
                VsxDialogs.Show(MESSAGE, "Unexpected issue",
                    MessageBoxButton.OK, VsxMessageBoxIcon.Error);
                return false;
            }
            return true;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Compiles the Z80 code file
        /// </summary>
        protected override async Task ExecuteAsync()
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            VmStateLoaded = false;
            GetItem(out var hierarchy, out var itemId);
            if (!(hierarchy is IVsProject project))
            {
                return;
            }
            project.GetMkDocument(itemId, out var itemFullPath);

            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            var vm = Package.MachineViewModel;

            // --- Prepare the machine to be in the appropriate mode
            if (vm.MachineState == VmState.Stopped || vm.MachineState == VmState.None)
            {
                vm.Start();
                await vm.Pause();
            }

            if (vm.MachineState != VmState.Paused)
            {
                VsxDialogs.Show("To load state file into the virtual machine, please pause it first.",
                                "The virtual machine is running");
                return;
            }

            Package.ShowToolWindow <SpectrumEmulatorToolWindow>();
            Package.StateFileManager.LoadVmStateFile(itemFullPath);
            vm.Machine.ForceScreenRefresh();
            VmStateLoaded = true;
        }
Exemplo n.º 4
0
 /// <summary>
 /// Override this method to define the action to execute on the main
 /// thread of Visual Studio -- finally
 /// </summary>
 protected override void FinallyOnMainThread()
 {
     base.FinallyOnMainThread();
     if (Package.Options.ConfirmCodeCompile && Output.ErrorCount == 0)
     {
         VsxDialogs.Show("The code has been successfully compiled.");
     }
 }
Exemplo n.º 5
0
 /// <summary>
 /// Override this method to define the action to execute on the main
 /// thread of Visual Studio -- finally
 /// </summary>
 protected override Task FinallyOnMainThreadAsync()
 {
     if (VmStateLoaded && Package.Options.ConfirmVmStateLoad)
     {
         VsxDialogs.Show("The VM state file has been loaded.");
     }
     return(Task.FromResult(0));
 }
 /// <summary>
 /// Override this method to define the action to execute on the main
 /// thread of Visual Studio -- finally
 /// </summary>
 protected override void FinallyOnMainThread()
 {
     Package.TestManager.CompilatioInProgress = false;
     if (Package.Options.ConfirmTestCompile && Output.ErrorCount == 0)
     {
         VsxDialogs.Show("The unit test code has been successfully compiled.");
     }
 }
 /// <summary>
 /// Override this method to define the action to execute on the main
 /// thread of Visual Studio -- finally
 /// </summary>
 protected override void FinallyOnMainThread()
 {
     base.FinallyOnMainThread();
     if (!IsCancelled && Package.Options.ConfirmCodeExport && Output.ErrorCount == 0)
     {
         VsxDialogs.Show("The code has been exported.");
     }
 }
Exemplo n.º 8
0
        /// <summary>
        /// Override this method to define the action to execute on the main
        /// thread of Visual Studio -- finally
        /// </summary>
        protected override async Task FinallyOnMainThreadAsync()
        {
            await base.FinallyOnMainThreadAsync();

            if (HostPackage.Options.ConfirmCodeCompile && Output.ErrorCount == 0)
            {
                VsxDialogs.Show("The code has been successfully compiled.");
            }
        }
Exemplo n.º 9
0
 /// <summary>
 /// Override this method to define the action to execute on the main
 /// thread of Visual Studio -- finally
 /// </summary>
 protected override Task FinallyOnMainThreadAsync()
 {
     Package.TestManager.CompilatioInProgress = false;
     if (Package.Options.ConfirmTestCompile && Output.ErrorCount == 0)
     {
         VsxDialogs.Show("The unit test code has been successfully compiled.");
     }
     return(Task.FromResult(0));
 }
Exemplo n.º 10
0
        /// <summary>
        /// Override this method to define the action to execute on the main
        /// thread of Visual Studio -- finally
        /// </summary>
        protected override async Task FinallyOnMainThreadAsync()
        {
            await base.FinallyOnMainThreadAsync();

            if (Success && !IsCancelled && Package.Options.ConfirmCodeExport && Output.ErrorCount == 0)
            {
                VsxDialogs.Show("The code has been exported.");
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Override this method to define the action to execute on the main
        /// thread of Visual Studio -- finally
        /// </summary>
        protected override void FinallyOnMainThread()
        {
            Package.CodeManager.CompilatioInProgress = false;
            var options = Package.Options;

            if (options.ConfirmCodeStart)
            {
                VsxDialogs.Show("The code has been started.");
            }
        }
Exemplo n.º 12
0
            protected override async Task ExecuteAsync()
            {
                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                var folder   = HostPackage.Options.VmStateSaveFileFolder;
                var filename = VsxDialogs.FileOpen(VMSTATE_FILTER, folder);

                if (filename == null)
                {
                    return;
                }

                // --- Stop the virtual machine, provided it runs
                var options      = HostPackage.Options;
                var pane         = OutputWindow.GetPane <SpectrumVmOutputPane>();
                var vm           = HostPackage.EmulatorViewModel;
                var machineState = vm.MachineState;

                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.
                    await HostPackage.EmulatorViewModel.Machine.Stop();

                    await Task.Delay(50);

                    if (vm.MachineState != VmState.Stopped)
                    {
                        const string MESSAGE = "The ZX Spectrum virtual machine did not stop.";
                        await pane.WriteLineAsync(MESSAGE);

                        VsxDialogs.Show(MESSAGE, "Unexpected issue",
                                        MessageBoxButton.OK, VsxMessageBoxIcon.Error);
                        return;
                    }
                }

                // --- Load the file and keep it paused
                VmStateFileManager.LoadVmStateFile(filename);
                HostPackage.EmulatorViewModel.ForceScreenRefresh();
                HostPackage.EmulatorViewModel.ForcePauseVmAfterStateRestore();
            }
Exemplo n.º 13
0
        /// <summary>
        /// Creates the compilation list file as set up in the package options
        /// </summary>
        /// <param name="hierarchy">Hierarchy object</param>
        /// <param name="itemId">Identifier of item to compile</param>
        private void CreateCompilationListFile(IVsHierarchy hierarchy, uint itemId)
        {
            var options = HostPackage.Options;

            if (!options.GenerateCompilationList ||
                options.GenerateForCompileOnly && !(this is CompileCodeCommand))
            {
                return;
            }

            // --- Create list file name
            if (!(hierarchy is IVsProject project))
            {
                return;
            }
            project.GetMkDocument(itemId, out var itemFullPath);
            var codeFile = Path.GetFileNameWithoutExtension(itemFullPath);
            var suffix   = string.IsNullOrWhiteSpace(options.CompilationFileSuffix)
                ? string.Empty
                : DateTime.Now.ToString(options.CompilationFileSuffix);
            var listFilename = $"{codeFile}{suffix}{options.CompilationFileExtension ?? ".list"}";
            var listFolder   = string.IsNullOrWhiteSpace(options.CompilationFileFolder)
                ? LIST_TMP_FOLDER
                : options.CompilationFileFolder;

            // -- Make sure list folder exists
            if (!Directory.Exists(listFolder))
            {
                Directory.CreateDirectory(listFolder);
            }

            // --- Save the list file
            var listContents     = CreateListFileContents();
            var fullListFileName = Path.Combine(listFolder, listFilename);

            try
            {
                File.WriteAllText(fullListFileName, listContents);
            }
            catch
            {
                VsxDialogs.Show($"Error when writing list file {fullListFileName}. "
                                + "The file name may contain invalid characters, or you miss file permissions.",
                                "Error when creating list file.", MessageBoxButton.OK, VsxMessageBoxIcon.Error);
                return;
            }

            if (options.AddCompilationToProject)
            {
                SpectrumProject.AddFileToProject(HostPackage.Options.CompilationProjectFolder,
                                                 fullListFileName, INVALID_FOLDER_MESSAGE, FILE_EXISTS_MESSAGE, false);
            }
        }
Exemplo n.º 14
0
        /// <summary>
        /// Save data blocks
        /// </summary>
        /// <param name="vm">Export parameters</param>
        /// <param name="blocksToSave">Collection of data blocks to save</param>
        private static void SaveDataBlocks(ExportZ80ProgramViewModel vm, IEnumerable <byte[]> blocksToSave)
        {
            try
            {
                // --- Create directory
                var dirName = Path.GetDirectoryName(vm.Filename);
                if (dirName != null && !Directory.Exists(dirName))
                {
                    Directory.CreateDirectory(dirName);
                }

                // --- Save data blocks
                if (vm.Format == ExportFormat.Tzx)
                {
                    using (var writer = new BinaryWriter(File.Create(vm.Filename)))
                    {
                        var header = new TzxHeader();
                        header.WriteTo(writer);

                        foreach (var block in blocksToSave)
                        {
                            var tzxBlock = new TzxStandardSpeedDataBlock
                            {
                                Data       = block,
                                DataLength = (ushort)block.Length
                            };
                            tzxBlock.WriteTo(writer);
                        }
                    }
                }
                else
                {
                    using (var writer = new BinaryWriter(File.Create(vm.Filename)))
                    {
                        foreach (var block in blocksToSave)
                        {
                            writer.Write((ushort)block.Length);
                            writer.Write(block);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                VsxDialogs.Show($"An error has been raised while exporting a program: {ex.Message}",
                                "Errorr when exporting file");
            }
        }
Exemplo n.º 15
0
 /// <summary>
 /// Override this method to define the async command body te execute on the
 /// background thread
 /// </summary>
 protected override async Task ExecuteAsync()
 {
     if (!(Package.MachineViewModel.SpectrumVm.FloppyDevice is FloppyDevice floppyDevice))
     {
         return;
     }
     try
     {
         await InsertFloppyAsync(floppyDevice, ItemPath);
     }
     catch (Exception)
     {
         VsxDialogs.Show("Cannot mount this virtual floppy disk file. It might be corrupt, or is inaccessible.",
                         "Error inserting floppy", MessageBoxButton.OK, VsxMessageBoxIcon.Exclamation);
     }
 }
Exemplo n.º 16
0
        /// <summary>
        /// Tests if the compiler is available.
        /// </summary>
        /// <returns>True, if the compiler is installed, and so available.</returns>
        public async Task <bool> IsAvailable()
        {
            var runner = new ZxbRunner(SpectNetPackage.Default.Options.ZxbPath, 10000);

            try
            {
                await runner.RunAsync(new ZxbOptions());
            }
            catch (Exception ex)
            {
                VsxDialogs.Show(string.Format(ZXB_NOT_FOUND_MESSAGE, ex.Message),
                                "Error when running ZXB", MessageBoxButton.OK, VsxMessageBoxIcon.Exclamation);
                return(false);
            }
            return(true);
        }
Exemplo n.º 17
0
            protected override void OnExecute()
            {
                var tw       = Package.GetToolWindow <TapeFileExplorerToolWindow>();
                var vm       = tw.Content.Vm;
                var filename = VsxDialogs.FileOpen(TZX_FILTER, vm.LatestPath);

                if (filename == null)
                {
                    return;
                }

                vm.FileName   = filename;
                vm.LatestPath = Path.GetDirectoryName(filename);
                vm.ReadFrom(filename);
                vm.Loaded = true;
                tw.Content.EditorControl.Vm = vm;
            }
Exemplo n.º 18
0
 /// <summary>
 /// Override this method to define the action to execute on the main
 /// thread of Visual Studio -- finally
 /// </summary>
 protected override Task FinallyOnMainThread()
 {
     base.FinallyOnMainThread();
     if (IsInInjectMode)
     {
         if (Package.Options.ConfirmInjectCode && CodeInjected)
         {
             VsxDialogs.Show("The code has been injected.");
         }
     }
     else
     {
         if (Package.Options.ConfirmCodeStart && Output.ErrorCount > 0)
         {
             VsxDialogs.Show("The code has been started.");
         }
     }
     return(Task.FromResult(0));
 }
Exemplo n.º 19
0
        /// <summary>
        /// Override this method to define the action to execute on the main
        /// thread of Visual Studio -- finally
        /// </summary>
        protected override async Task FinallyOnMainThreadAsync()
        {
            await base.FinallyOnMainThreadAsync();

            if (IsInInjectMode)
            {
                if (HostPackage.Options.ConfirmInjectCode && CodeInjected)
                {
                    VsxDialogs.Show("The code has been injected.");
                }
            }
            else
            {
                if (HostPackage.Options.ConfirmCodeStart && Output.ErrorCount > 0)
                {
                    VsxDialogs.Show("The code has been started.");
                }
            }
        }
Exemplo n.º 20
0
            protected override Task ExecuteOnMainThreadAsync()
            {
                var folder   = HostPackage.Options.VmStateSaveFileFolder;
                var filename = VsxDialogs.FileSave(VMSTATE_FILTER, folder);

                if (filename != null)
                {
                    var spectrum = HostPackage.EmulatorViewModel.Machine.SpectrumVm;
                    var state    = spectrum.GetVmState(HostPackage.Solution.ActiveProject.ModelName);

                    folder = Path.GetDirectoryName(filename);
                    if (folder != null && !Directory.Exists(folder))
                    {
                        Directory.CreateDirectory(folder);
                    }
                    File.WriteAllText(filename, state);
                }
                return(Task.FromResult(0));
            }
Exemplo n.º 21
0
            protected override void OnExecute()
            {
                var folder   = Package.Options.VmStateSaveFileFolder;
                var filename = VsxDialogs.FileSave(VMSTATE_FILTER, folder);

                if (filename == null)
                {
                    return;
                }

                var spectrum = Package.MachineViewModel.SpectrumVm;
                var state    = spectrum.GetVmState(Package.CodeDiscoverySolution.CurrentProject.ModelName);

                folder = Path.GetDirectoryName(filename);
                if (folder != null && !Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                }
                File.WriteAllText(filename, state);
            }
Exemplo n.º 22
0
        /// <summary>
        /// Sets the active project to the current project file
        /// </summary>
        protected async override Task ExecuteAsync()
        {
            // --- Collect export parameters from the UI
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            if (DisplayCreateVfddDialog(out var vm))
            {
                return;
            }

            // --- Create a temporary file
            string fullPath;

            try
            {
                var filename = Path.ChangeExtension(Path.GetFileName(vm.Filename), ".vfdd");
                var userPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
                fullPath = Path.Combine(Path.Combine(userPath, "SpectNetFloppies"), filename);
                VirtualFloppyFile.CreateSpectrumFloppyFile(fullPath, vm.Format);
            }
            catch (Exception ex)
            {
                VsxDialogs.Show($"Error: {ex.Message}", "Error creating virtual floppy disk file");
                return;
            }

            // --- Add the temp file to the project
            SpectrumProject.AddFileToProject(SpectNetPackage.Default.Options.VfddFolder, fullPath,
                                             INVALID_FOLDER_MESSAGE, FILE_EXISTS_MESSAGE);

            // --- Remove the temp file
            try
            {
                File.Delete(fullPath);
            }
            catch (Exception)
            {
                // --- This exception is intentionally ignored
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Exports the memory of the specified virtual machine
        /// </summary>
        /// <param name="spectrumVm"></param>
        public void ExportMemory(ISpectrumVm spectrumVm)
        {
            // --- Parse addresses
            if (!ushort.TryParse(ExportParams.StartAddress, out var startAddress))
            {
                return;
            }
            if (!ushort.TryParse(ExportParams.EndAddress, out var endAddress))
            {
                return;
            }
            try
            {
                var contents = spectrumVm.MemoryDevice.CloneMemory()
                               .Skip(startAddress)
                               .Take(endAddress - startAddress + 1)
                               .ToArray();
                var dirName = Path.GetDirectoryName(ExportParams.Filename);
                if (!string.IsNullOrEmpty(dirName) && !Directory.Exists(dirName))
                {
                    Directory.CreateDirectory(dirName);
                }
                File.WriteAllBytes(ExportParams.Filename, contents);
            }
            catch (Exception ex)
            {
                VsxDialogs.Show($"Error while exporting to file {ExportParams.Filename}: {ex.Message}",
                                "Export disassembly error.", MessageBoxButton.OK, VsxMessageBoxIcon.Error);
            }

            if (!ExportParams.AddToProject)
            {
                return;
            }

            SpectrumProject.AddFileToProject(SpectNetPackage.Default.Options.MemoryExportFolder,
                                             ExportParams.Filename,
                                             INVALID_FOLDER_MESSAGE, FILE_EXISTS_MESSAGE);
        }
Exemplo n.º 24
0
        /// <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);
        }
            protected override Task ExecuteAsync()
            {
                var tw       = SpectNetPackage.Default.GetToolWindow <TapeFileExplorerToolWindow>();
                var vm       = tw.Content.Vm;
                var filename = VsxDialogs.FileOpen(TZX_FILTER, vm.LatestPath);

                if (filename == null)
                {
                    return(Task.FromResult(0));
                }

                vm.FileName   = filename;
                vm.LatestPath = Path.GetDirectoryName(filename);
                vm.ReadFrom(filename);
                vm.Loaded = true;
                tw.Content.EditorControl.Vm = vm;
                if (vm.Blocks.Count > 0)
                {
                    vm.Blocks[0].IsSelected = true;
                }
                vm.BlockSelectedCommand.Execute(null);
                return(Task.FromResult(0));
            }
Exemplo n.º 26
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");
            }
        }
Exemplo n.º 27
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);
        }
        /// <summary>
        /// Updates the RAM annotation file according to changes
        /// </summary>
        private void OnAnnotationFileChanged(object sender, EventArgs eventArgs)
        {
            var project = SpectNetPackage.Default.ActiveProject;
            var annFile = project?.DefaultAnnotationItem
                          ?? project?.AnnotationProjectItems?.FirstOrDefault();

            RamBankAnnotations.Clear();
            if (annFile == null)
            {
                return;
            }

            RamBankAnnotationFile = annFile.Filename;
            try
            {
                var disAnn = File.ReadAllText(annFile.Filename);
                DisassemblyAnnotation.DeserializeBankAnnotations(disAnn, out var annotations);
                RamBankAnnotations = annotations;
            }
            catch (Exception ex)
            {
                VsxDialogs.Show(ex.Message, "Error loading annotation file", MessageBoxButton.OK, VsxMessageBoxIcon.Error);
            }
        }
Exemplo n.º 29
0
        /// <summary>
        /// Adds the exported file to the project structure
        /// </summary>
        /// <param name="projectFolder">Project folder to add the file</param>
        /// <param name="filename">Filename to add to the project</param>
        /// <param name="invFolderMessage">Message to display when folder name is invalid</param>
        /// <param name="fileExistsMessage">Message to display when file already exists</param>
        /// <param name="confirmOverwrite">When a file exists, the user must confirm overwriting it</param>
        public static void AddFileToProject(string projectFolder, string filename, string invFolderMessage = null,
                                            string fileExistsMessage = null, bool confirmOverwrite = true)
        {
            var folderSegments = projectFolder.Split(new[] { '/', '\\' },
                                                     StringSplitOptions.RemoveEmptyEntries);

            foreach (var segment in folderSegments)
            {
                bool valid;
                try
                {
                    valid = !Path.IsPathRooted(segment);
                }
                catch
                {
                    valid = false;
                }
                if (!valid)
                {
                    VsxDialogs.Show(invFolderMessage ?? DEFAULT_INV_FOLDER_MESSAGE,
                                    "Invalid characters in path");
                    return;
                }
            }

            // --- Obtain the project and its items
            var project      = SpectNetPackage.Default.ActiveRoot;
            var projectItems = project.ProjectItems;
            var currentIndex = 0;
            var find         = true;

            while (currentIndex < folderSegments.Length)
            {
                // --- Find or create folder segments
                var segment = folderSegments[currentIndex];
                if (find)
                {
                    // --- We are in "find" mode
                    var found = false;
                    // --- Search for the folder segment
                    foreach (ProjectItem projItem in projectItems)
                    {
                        var folder = projItem.Properties.Item("FolderName").Value?.ToString();
                        if (string.Compare(folder, segment, StringComparison.InvariantCultureIgnoreCase) == 0)
                        {
                            // --- We found the folder, we'll go no with search within this segment
                            projectItems = projItem.ProjectItems;
                            found        = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        // --- Move to "create" mode
                        find = false;
                    }
                }
                if (!find)
                {
                    // --- We're in create mode, add and locate the new folder segment
                    var found = false;
                    projectItems.AddFolder(segment);
                    var parent = projectItems.Parent;
                    if (parent is Project projectType)
                    {
                        projectItems = projectType.ProjectItems;
                    }
                    else if (parent is ProjectItem itemType)
                    {
                        projectItems = itemType.ProjectItems;
                    }
                    foreach (ProjectItem projItem in projectItems)
                    {
                        var folder = projItem.Properties.Item("FolderName").Value?.ToString();
                        if (string.Compare(folder, segment, StringComparison.InvariantCultureIgnoreCase) == 0)
                        {
                            // --- We found the folder, we'll go no with search within this segment
                            projectItems = projItem.ProjectItems;
                            found        = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        // --- This should not happen...
                        VsxDialogs.Show($"The folder segment {segment} could not be created.",
                                        "Adding project item failed");
                        return;
                    }
                }

                // --- Move to the next segment
                currentIndex++;
            }

            // --- Check if that filename exists within the project folder
            var         tempFile = Path.GetFileName(filename);
            ProjectItem toDelete = null;

            foreach (ProjectItem projItem in projectItems)
            {
                var file = Path.GetFileName(projItem.FileNames[0]);
                if (string.Compare(file, tempFile,
                                   StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    if (confirmOverwrite)
                    {
                        var answer = VsxDialogs.Show(fileExistsMessage ?? DEFAULT_FILE_EXISTS_MESSAGE,
                                                     "File already exists",
                                                     MessageBoxButton.YesNo, VsxMessageBoxIcon.Question, 1);
                        if (answer == VsxDialogResult.No)
                        {
                            return;
                        }
                    }
                    toDelete = projItem;
                    break;
                }
            }

            // --- Remove existing file
            toDelete?.Delete();

            // --- Add the item to the appropriate item
            projectItems.AddFromFileCopy(filename);

            // --- Refresh the solution's content
            SpectNetPackage.Default.ActiveProject.CollectItems();
        }
Exemplo n.º 30
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();
        }