/// <summary>
        /// Folder for the test TAP files
        /// </summary>
        /// <summary>
        /// Creates a new player for the specified resource
        /// </summary>
        /// <param name="tapResource"></param>
        /// <returns></returns>
        public static CommonTapeFilePlayer CreatePlayer(string tapResource)
        {
            var tzxReader = GetResourceReader(tapResource);
            var player    = new CommonTapeFilePlayer(tzxReader);

            player.ReadContent();
            return(player);
        }
        /// <summary>
        /// Creates screen blocks from the specified screen file
        /// </summary>
        /// <param name="screenFile">Screen file name</param>
        /// <returns></returns>
        private List <byte[]> CreatScreenBlocks(string screenFile)
        {
            var result = new List <byte[]>();

            using (var reader = new BinaryReader(File.OpenRead(screenFile)))
            {
                var player = new CommonTapeFilePlayer(reader);
                player.ReadContent();
                result.Add(((ITapeData)player.DataBlocks[0]).Data);
                result.Add(((ITapeData)player.DataBlocks[1]).Data);
            }
            return(result);
        }
Beispiel #3
0
        /// <summary>
        /// Selects the screen file for export
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnSelectScreenFileClick(object sender, RoutedEventArgs e)
        {
            // --- Get the file name
            var dialog = new OpenFileDialog
            {
                Filter = "TZX files (*.tzx)|*.tzx|TAP files (*.tap)|*.tap",
                Title  = "Select the screen file"
            };

            if (dialog.ShowDialog() != true)
            {
                return;
            }

            // --- Save and test for ZX Spectrum scrren file
            Vm.ScreenFile = dialog.FileName;
            if (!CommonTapeFilePlayer.CheckScreenFile(Vm.ScreenFile))
            {
                MessageBox.Show("The selected file is not a valid ZX Spectrum screen file.",
                                "Invalid Screen File", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        /// <summary>
        /// Compiles the Z80 code file
        /// </summary>
        protected override async Task ExecuteAsync()
        {
            // --- Prepare the appropriate file to export
            Success = true;

            // --- Step #1: Compile the code
            if (!await CompileCode())
            {
                Success = false;
                return;
            }

            // --- Step #2: Check for zero code length
            if (Output.Segments.Sum(s => s.EmittedCode.Count) == 0)
            {
                VsxDialogs.Show("The length of the compiled code is 0, " +
                                "so there is no code to export.",
                                "No code to export.");
                Success = false;
                return;
            }

            // --- Step #3: Collect export parameters from the UI
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

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

            // --- Step #4: Execute pre-export event
            var codeManager = SpectNetPackage.Default.CodeManager;

            PreexportError  = null;
            PostexportError = null;
            var eventOutput = await codeManager.RunPreExportEvent(ItemFullPath, vm.Filename);

            if (eventOutput != null)
            {
                PreexportError = eventOutput;
                CleanupError   = await codeManager.RunBuildErrorEvent(ItemFullPath);

                DisplayBuildErrors();
                Success = false;
                return;
            }

            if (vm.Format == ExportFormat.IntelHex)
            {
                // --- Step #5: Export to Intel format
                SaveIntelHexFile(vm.Filename, Output);
            }
            else
            {
                // --- Step #5: Check screen file again
                var useScreenFile = !string.IsNullOrEmpty(vm.ScreenFile) && vm.ScreenFile.Trim().Length > 0;
                if (useScreenFile && !CommonTapeFilePlayer.CheckScreenFile(vm.ScreenFile))
                {
                    VsxDialogs.Show("The specified screen file cannot be read as a ZX Spectrum compatible screen file.",
                                    "Screen file error.", MessageBoxButton.OK, VsxMessageBoxIcon.Error);
                    Success = false;
                    return;
                }

                // --- Step #6: Create code segments
                var           codeBlocks   = CreateTapeBlocks(vm.Name, vm.SingleBlock);
                List <byte[]> screenBlocks = null;
                if (useScreenFile)
                {
                    screenBlocks = CreatScreenBlocks(vm.ScreenFile);
                }

                // --- Step #7: Create Auto Start header block, if required
                var blocksToSave = new List <byte[]>();
                if (!ushort.TryParse(vm.StartAddress, out var startAddress))
                {
                    startAddress = (ushort)ExportStartAddress;
                }

                if (vm.AutoStartEnabled)
                {
                    var autoStartBlocks = CreateAutoStartBlock(
                        vm.Name,
                        useScreenFile,
                        vm.AddPause0,
                        vm.Border,
                        startAddress,
                        vm.ApplyClear
                            ? Output.Segments.Min(s => s.StartAddress)
                            : (ushort?)null);
                    blocksToSave.AddRange(autoStartBlocks);
                }

                // --- Step #8: Save all the blocks
                if (screenBlocks != null)
                {
                    blocksToSave.AddRange(screenBlocks);
                }

                blocksToSave.AddRange(codeBlocks);
                SaveDataBlocks(vm, blocksToSave);

                if (vm.AddToProject)
                {
                    // --- Step #9: Add the saved item to the project
                    // --- Check path segment names
                    SpectrumProject.AddFileToProject(SpectNetPackage.Default.Options.TapeFolder, vm.Filename,
                                                     INVALID_FOLDER_MESSAGE, FILE_EXISTS_MESSAGE);
                }
            }

            // --- Run post-export event
            // --- Execute post-build event
            eventOutput = await codeManager.RunPostExportEvent(ItemFullPath, vm.Filename);

            if (eventOutput != null)
            {
                PostexportError = eventOutput;
                CleanupError    = await codeManager.RunBuildErrorEvent(ItemFullPath);

                DisplayBuildErrors();
                Success = false;
            }
        }
        /// <summary>
        /// Exports the specified compiler output
        /// </summary>
        /// <param name="output">Compiler output</param>
        /// <param name="programName">Name of the program</param>
        /// <param name="vm">Export options</param>
        /// <returns></returns>
        public static int ExportCompiledCode(AssemblerOutput output, ExportZ80ProgramViewModel vm)
        {
            var oldExt = vm.Format;

            vm.Format = ExportFormat.Unknown;
            vm.Format = oldExt;

            if (vm.Format == ExportFormat.IntelHex)
            {
                SaveIntelHexFile(vm.Filename, output);
                return(0);
            }

            // --- Check for screen file error
            var useScreenFile = !string.IsNullOrEmpty(vm.ScreenFile) && vm.ScreenFile.Trim().Length > 0;

            if (useScreenFile && !CommonTapeFilePlayer.CheckScreenFile(vm.ScreenFile))
            {
                return(1);
            }

            // --- Step #6: Create code segments
            var           codeBlocks   = CreateTapeBlocks(output, vm.Name, vm.SingleBlock);
            List <byte[]> screenBlocks = null;

            if (useScreenFile)
            {
                screenBlocks = CreateScreenBlocks(vm.ScreenFile);
            }

            // --- Step #7: Create Auto Start header block, if required
            var blocksToSave = new List <byte[]>();

            if (!ushort.TryParse(vm.StartAddress, out var startAddress))
            {
                startAddress = (ushort)(output == null
                    ? -1
                    : output.ExportEntryAddress
                                        ?? output.EntryAddress
                                        ?? output.Segments[0].StartAddress);
            }

            if (vm.AutoStartEnabled)
            {
                var autoStartBlocks = CreateAutoStartBlock(
                    output,
                    vm.Name,
                    useScreenFile,
                    vm.AddPause0,
                    vm.Border,
                    startAddress,
                    vm.ApplyClear
                        ? output.Segments.Min(s => s.StartAddress)
                        : (ushort?)null);
                blocksToSave.AddRange(autoStartBlocks);
            }

            // --- Step #8: Save all the blocks
            if (screenBlocks != null)
            {
                blocksToSave.AddRange(screenBlocks);
            }

            blocksToSave.AddRange(codeBlocks);
            SaveDataBlocks(vm, blocksToSave);
            return(0);
        }
        /// <summary>
        /// Compiles the Z80 code file
        /// </summary>
        protected override async Task ExecuteAsync()
        {
            // --- Prepare the appropriate file to export
            Success = true;
            GetCodeItem(out var hierarchy, out var itemId);

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

            // --- Step #2: Check for zero code length
            if (Output.Segments.Sum(s => s.EmittedCode.Count) == 0)
            {
                VsxDialogs.Show("The length of the compiled code is 0, " +
                                "so there is no code to export.",
                                "No code to export.");
                Success = false;
                return;
            }

            // --- Step #2: Collect export parameters from the UI
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

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

            if (vm.Format == ExportFormat.IntelHex)
            {
                Package.CodeManager.SaveIntelHexFile(vm.Filename, Output);
                return;
            }

            // --- Step #3: Check screen file again
            var useScreenFile = !string.IsNullOrEmpty(vm.ScreenFile) && vm.ScreenFile.Trim().Length > 0;

            if (useScreenFile && !CommonTapeFilePlayer.CheckScreenFile(vm.ScreenFile))
            {
                VsxDialogs.Show("The specified screen file cannot be read as a ZX Spectrum compatible screen file.",
                                "Screen file error.", MessageBoxButton.OK, VsxMessageBoxIcon.Error);
                Success = false;
                return;
            }

            // --- Step #4: Create code segments
            var           codeBlocks   = Package.CodeManager.CreateTapeBlocks(vm.Name, Output, vm.SingleBlock);
            List <byte[]> screenBlocks = null;

            if (useScreenFile)
            {
                screenBlocks = Package.CodeManager.CreatScreenBlocks(vm.ScreenFile);
            }

            // --- Step #5: Create Auto Start header block, if required
            var blocksToSave = new List <byte[]>();

            if (!ushort.TryParse(vm.StartAddress, out var startAddress))
            {
                startAddress = (ushort)ExportStartAddress;
            }
            var autoStartBlocks = Package.CodeManager.CreateAutoStartBlock(
                vm.Name,
                useScreenFile,
                vm.AddPause0,
                vm.Border,
                codeBlocks.Count >> 1,
                startAddress,
                vm.ApplyClear
                    ? Output.Segments.Min(s => s.StartAddress)
                    : (ushort?)null);

            blocksToSave.AddRange(autoStartBlocks);

            // --- Step #6: Save all the blocks
            if (screenBlocks != null)
            {
                blocksToSave.AddRange(screenBlocks);
            }
            blocksToSave.AddRange(codeBlocks);
            SaveDataBlocks(vm, blocksToSave);

            if (!vm.AddToProject)
            {
                return;
            }

            // --- Step #6: Add the saved item to the project
            // --- Check path segment names
            DiscoveryProject.AddFileToProject(Package.Options.TapeFolder, vm.Filename,
                                              INVALID_FOLDER_MESSAGE, FILE_EXISTS_MESSAGE);
        }