/* * Copyright 2018 faddenSoft * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.ComponentModel; using Asm65; namespace SourceGen.AsmGen { /// /// Common interface for generating assembler-specific source code. /// public interface IGenerator { /// /// Returns some strings and format options for use in for the display list, configurable /// through the app settings "quick set" feature. These are not used when generating /// source code. /// /// This may be called on an unconfigured IGenerator. /// /// Table of pseudo-op names. /// Format configuration. void GetDefaultDisplayFormat(out PseudoOp.PseudoOpNames pseudoOps, out Formatter.FormatConfig formatConfig); /// /// Configure generator. Must be called before calling any other method or using /// properties, unless otherwise noted. /// /// Project to generate source for. /// Directory in which to create output files. /// Name to use as base for filenames. /// Version of assembler to target. Pass in null /// to target latest known version. /// App settings object. void Configure(DisasmProject project, string workDirectory, string fileNameBase, AssemblerVersion asmVersion, AppSettings settings); /// /// Project object with file data and Anattribs. /// DisasmProject Project { get; } /// /// Source code formatter. /// Formatter SourceFormatter { get; } /// /// Application settings. /// AppSettings Settings { get; } /// /// Assembler-specific behavior. Used to handle quirky behavior for things that /// are otherwise managed by common code. /// AssemblerQuirks Quirks { get; } /// /// Label localization object. Behavior is assembler-specific. /// LabelLocalizer Localizer { get; } /// /// Generates source files on a background thread. Method must not make any UI calls. /// /// Async work object, used to report progress updates and /// check for cancellation. /// List of pathnames of generated files. List GenerateSource(BackgroundWorker worker); /// /// Provides an opportunity for the assembler to replace a mnemonic with another. This /// is primarily intended for undocumented ops, which don't have standard mnemonics, /// and hence can vary between assemblers. /// /// Opcode to replace. /// Replacement mnemonic, an empty string if the original is fine, or /// null if the op is not supported at all and should be emitted as hex. string ReplaceMnemonic(OpDef op); /// /// Generates an opcode/operand pair for a short sequence of bytes (1-4 bytes). /// Does not produce any source output. /// /// Offset to data. /// Number of bytes (1-4). /// Opcode mnemonic. /// Formatted operand. void GenerateShortSequence(int offset, int length, out string opcode, out string operand); /// /// Outputs zero or more lines of assembler configuration. This comes after the /// header comment but before any directives. Useful for configuring the CPU type /// and assembler options. /// void OutputAsmConfig(); /// /// Outputs one or more lines of data for the specified offset. /// /// Offset to data. void OutputDataOp(int offset); /// /// Outputs an equate directive. The numeric value is already formatted. /// /// Symbol label. /// Formatted value. /// End-of-line comment. void OutputEquDirective(string name, string valueStr, string comment); /// /// Outputs a code origin directive. /// /// Offset of code targeted to new address. /// 24-bit address. void OutputOrgDirective(int offset, int address); /// /// Notify the assembler of a change in register width. /// /// Merlin32 always sets both values (e.g. "MX %00"), cc65 sets each register /// individually (".A16", ".I8"). We need to accommodate both styles. /// /// Offset of change. /// Previous value for M flag. /// Previous value for X flag. /// New value for M flag. /// New value for X flag. void OutputRegWidthDirective(int offset, int prevM, int prevX, int newM, int newX); /// /// Output a line of source code. All elements must be fully formatted, except for /// certain assembler-specific things like ':' on labels. The items will be padded /// with spaces to fit specific column widths. /// /// Optional label. /// Opcode mnemonic. /// Operand; may be empty. /// Optional comment. void OutputLine(string label, string opcode, string operand, string comment); /// /// Output a line of source code. This will be output as-is. /// /// Full text of line to outut. void OutputLine(string fullLine); } public class AssemblerQuirks { /// /// Are the arguments to MVN/MVP reversed? /// public bool BlockMoveArgsReversed { get; set; } /// /// Does the assembler configure assembler widths based on SEP/REP, but doesn't /// track the emulation bit? /// public bool TracksSepRepNotEmu { get; set; } /// /// Is the assembler unable to generate relative branches that wrap around banks? /// (Note this affects long-distance BRLs that don't appear to wrap.) /// public bool NoPcRelBankWrap { get; set; } } }