Пример #1
0
        int WriteOutput(string disassembly)
        {
            // no errors finish up
            // save to disk
            var section    = _services.Options.OutputSection;
            var outputFile = _services.Options.OutputFile;
            var objectCode = _services.Output.GetCompilation(section);

            if (!string.IsNullOrEmpty(_services.Options.Patch))
            {
                if (!string.IsNullOrEmpty(_services.Options.OutputFile) ||
                    !string.IsNullOrEmpty(_services.Options.Format))
                {
                    _services.Log.LogEntrySimple("Output options ignored for patch mode.", false);
                }
                if (_services.Options.LabelsAddressesOnly && string.IsNullOrEmpty(_services.Options.LabelFile))
                {
                    _services.Log.LogEntrySimple("Label listing not specified; option '-labels-addresses-only' ignored.",
                                                 false);
                }
                try
                {
                    var offsetLine = new Preprocessor(_processorOptions).ProcessDefine("patch=" + _services.Options.Patch);
                    var patchExp   = offsetLine.Operands.GetIterator();
                    var offset     = _services.Evaluator.Evaluate(patchExp, 0, ushort.MaxValue);
                    if (patchExp.Current != null || _services.PassNeeded)
                    {
                        throw new Exception();
                    }
                    var filePath  = Preprocessor.GetFullPath(outputFile, _services.Options.IncludePath);
                    var fileBytes = File.ReadAllBytes(filePath);
                    Array.Copy(objectCode.ToArray(), 0, fileBytes, (int)offset, objectCode.Count);
                    File.WriteAllBytes(filePath, fileBytes);
                }
                catch
                {
                    throw new Exception($"Cannot patch file \"{outputFile}\". One or more arguments is not valid.");
                }
            }
            else
            {
                var formatProvider = _services.FormatSelector?.Invoke(_services.CPU, _services.OutputFormat);
                if (formatProvider != null)
                {
                    var startAddress = _services.Output.ProgramStart;
                    if (!string.IsNullOrEmpty(section))
                    {
                        startAddress = _services.Output.GetSectionStart(section);
                    }
                    var format = _services.Options.CaseSensitive ?
                                 _services.OutputFormat :
                                 _services.OutputFormat.ToLower();
                    var info = new FormatInfo(outputFile, format, startAddress, objectCode);
                    File.WriteAllBytes(outputFile, formatProvider.GetFormat(info).ToArray());
                }
                else
                {
                    File.WriteAllBytes(outputFile, objectCode.ToArray());
                }
            }
            // write disassembly
            if (!string.IsNullOrEmpty(disassembly) && !string.IsNullOrEmpty(_services.Options.ListingFile))
            {
                File.WriteAllText(_services.Options.ListingFile, disassembly);
            }

            // write labels
            if (!string.IsNullOrEmpty(_services.Options.LabelFile))
            {
                File.WriteAllText(_services.Options.LabelFile, _services.SymbolManager.ListLabels(!_services.Options.LabelsAddressesOnly));
            }

            if (_services.Log.HasWarnings)
            {
                _services.Log.DumpWarnings();
            }
            if (!_services.Options.NoStats)
            {
                Console.WriteLine("\n*********************************");
                Console.WriteLine($"Assembly start: ${_services.Output.ProgramStart:X4}");
                if (_services.Output.ProgramEnd > BinaryOutput.MaxAddress && _services.Options.LongAddressing)
                {
                    Console.WriteLine($"Assembly end:   ${_services.Output.ProgramEnd:X6}");
                }
                else
                {
                    Console.WriteLine($"Assembly end:   ${_services.Output.ProgramEnd & BinaryOutput.MaxAddress:X4}");
                }
                Console.WriteLine($"Passes: {_services.CurrentPass + 1}");
            }
            return(objectCode.Count);
        }