// IGenerator public List <string> GenerateSource(BackgroundWorker worker) { List <string> pathNames = new List <string>(1); string fileName = mFileNameBase + ASM_FILE_SUFFIX; string pathName = Path.Combine(mWorkDirectory, fileName); pathNames.Add(pathName); Formatter.FormatConfig config = new Formatter.FormatConfig(); GenCommon.ConfigureFormatterFromSettings(Settings, ref config); SetFormatConfigValues(ref config); SourceFormatter = new Formatter(config); string msg = string.Format(Res.Strings.PROGRESS_GENERATING_FMT, pathName); worker.ReportProgress(0, msg); mLocalizer = new LabelLocalizer(Project); if (!Settings.GetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false)) { mLocalizer.LocalPrefix = "@"; mLocalizer.Analyze(); } mLocalizer.FixOpcodeLabels(); // Use UTF-8 encoding, without a byte-order mark. using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { mOutStream = sw; if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { OutputLine(SourceFormatter.FullLineCommentDelimiter + string.Format(Res.Strings.GENERATED_FOR_VERSION_FMT, "acme", V0_96_4, AsmAcme.OPTIONS)); } if (HasNonZeroBankCode()) { // don't try OutputLine(SourceFormatter.FullLineCommentDelimiter + "ACME can't handle 65816 code that lives outside bank zero"); int orgAddr = Project.AddrMap.Get(0); OutputOrgDirective(0, orgAddr); OutputDenseHex(0, Project.FileData.Length, string.Empty, string.Empty); } else { GenCommon.Generate(this, sw, worker); } if (mInPseudoPcBlock) { OutputLine(string.Empty, CLOSE_PSEUDOPC, string.Empty, string.Empty); } } mOutStream = null; return(pathNames); }
// IGenerator public List <string> GenerateSource(BackgroundWorker worker) { List <string> pathNames = new List <string>(1); string fileName = mFileNameBase + ASM_FILE_SUFFIX; string pathName = Path.Combine(mWorkDirectory, fileName); pathNames.Add(pathName); Formatter.FormatConfig config = new Formatter.FormatConfig(); GenCommon.ConfigureFormatterFromSettings(Settings, ref config); config.mForceAbsOpcodeSuffix = string.Empty; config.mForceLongOpcodeSuffix = string.Empty; config.mForceAbsOperandPrefix = "a:"; // absolute config.mForceLongOperandPrefix = "f:"; // far config.mEndOfLineCommentDelimiter = ";"; config.mFullLineCommentDelimiterBase = ";"; config.mBoxLineCommentDelimiter = ";"; config.mAllowHighAsciiCharConst = false; config.mExpressionMode = Formatter.FormatConfig.ExpressionMode.Simple; SourceFormatter = new Formatter(config); string msg = string.Format(Properties.Resources.PROGRESS_GENERATING_FMT, pathName); worker.ReportProgress(0, msg); mLocalizer = new LabelLocalizer(Project); if (!Settings.GetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false)) { mLocalizer.LocalPrefix = "@"; mLocalizer.Analyze(); } // Use UTF-8 encoding, without a byte-order mark. using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { mOutStream = sw; if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { //if (mAsmVersion.IsValid && mAsmVersion <= V2_17) { // OutputLine(SourceFormatter.FullLineCommentDelimiter + // string.Format(Properties.Resources.GENERATED_FOR_VERSION, // "cc65", mAsmVersion.ToString())); //} else { // OutputLine(SourceFormatter.FullLineCommentDelimiter + // string.Format(Properties.Resources.GENERATED_FOR_LATEST, "cc65")); //} // Currently generating code for v2.17. OutputLine(SourceFormatter.FullLineCommentDelimiter + string.Format(Properties.Resources.GENERATED_FOR_VERSION, "cc65", V2_17)); } GenCommon.Generate(this, sw, worker); } mOutStream = null; return(pathNames); }
// IGenerator public void Configure(DisasmProject project, string workDirectory, string fileNameBase, AssemblerVersion asmVersion, AppSettings settings) { Debug.Assert(project != null); Debug.Assert(!string.IsNullOrEmpty(workDirectory)); Debug.Assert(!string.IsNullOrEmpty(fileNameBase)); Project = project; Quirks = new AssemblerQuirks(); Quirks.StackIntOperandIsImmediate = true; Quirks.LeadingUnderscoreSpecial = true; Quirks.Need24BitsForAbsPBR = true; Quirks.BitNumberIsArg = true; mWorkDirectory = workDirectory; mFileNameBase = fileNameBase; Settings = settings; mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false); AssemblerConfig config = AssemblerConfig.GetConfig(settings, AssemblerInfo.Id.Tass64); mColumnWidths = (int[])config.ColumnWidths.Clone(); mHasPrgHeader = GenCommon.HasPrgHeader(project); }
// IGenerator public GenerationResults GenerateSource(BackgroundWorker worker) { List <string> pathNames = new List <string>(1); string fileName = mFileNameBase + ASM_FILE_SUFFIX; string pathName = Path.Combine(mWorkDirectory, fileName); pathNames.Add(pathName); Formatter.FormatConfig config = new Formatter.FormatConfig(); GenCommon.ConfigureFormatterFromSettings(Settings, ref config); SetFormatConfigValues(ref config); // Configure delimiters for single-character operands. Formatter.DelimiterSet charDelimSet = new Formatter.DelimiterSet(); charDelimSet.Set(CharEncoding.Encoding.C64Petscii, Formatter.SINGLE_QUOTE_DELIM); charDelimSet.Set(CharEncoding.Encoding.C64ScreenCode, Formatter.SINGLE_QUOTE_DELIM); charDelimSet.Set(CharEncoding.Encoding.Ascii, Formatter.SINGLE_QUOTE_DELIM); charDelimSet.Set(CharEncoding.Encoding.HighAscii, new Formatter.DelimiterDef(string.Empty, '\'', '\'', " | $80")); config.mCharDelimiters = charDelimSet; SourceFormatter = new Formatter(config); string msg = string.Format(Res.Strings.PROGRESS_GENERATING_FMT, pathName); worker.ReportProgress(0, msg); mLocalizer = new LabelLocalizer(Project); mLocalizer.LocalPrefix = "_"; mLocalizer.QuirkNoOpcodeMnemonics = true; mLocalizer.Analyze(); bool needLongAddress = Project.FileDataLength > 65536 + (mHasPrgHeader ? 2 : 0); string extraOptions = string.Empty + (needLongAddress ? AsmTass64.LONG_ADDRESS : string.Empty) + (mHasPrgHeader ? string.Empty : AsmTass64.NOSTART); mPcDepth = 0; mFirstIsOpen = true; // Use UTF-8 encoding, without a byte-order mark. using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { mOutStream = sw; if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { OutputLine(SourceFormatter.FullLineCommentDelimiter + string.Format(Res.Strings.GENERATED_FOR_VERSION_FMT, "64tass", mAsmVersion, AsmTass64.BASE_OPTIONS + extraOptions)); } GenCommon.Generate(this, sw, worker); } mOutStream = null; return(new GenerationResults(pathNames, extraOptions)); }
// IGenerator public List <string> GenerateSource(BackgroundWorker worker) { List <string> pathNames = new List <string>(1); string pathName = Path.Combine(mWorkDirectory, mFileNameBase + ASM_FILE_SUFFIX); pathNames.Add(pathName); string cfgName = Path.Combine(mWorkDirectory, mFileNameBase + CFG_FILE_SUFFIX); pathNames.Add(cfgName); Formatter.FormatConfig config = new Formatter.FormatConfig(); GenCommon.ConfigureFormatterFromSettings(Settings, ref config); SetFormatConfigValues(ref config); SourceFormatter = new Formatter(config); string msg = string.Format(Res.Strings.PROGRESS_GENERATING_FMT, pathName); worker.ReportProgress(0, msg); mLocalizer = new LabelLocalizer(Project); if (!Settings.GetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false)) { mLocalizer.LocalPrefix = "@"; mLocalizer.QuirkVariablesEndScope = true; mLocalizer.Analyze(); } mLocalizer.FixOpcodeLabels(); // Use UTF-8 encoding, without a byte-order mark. using (StreamWriter sw = new StreamWriter(cfgName, false, new UTF8Encoding(false))) { GenerateLinkerScript(sw); } using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { mOutStream = sw; if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { //if (mAsmVersion.IsValid && mAsmVersion <= V2_17) { // OutputLine(SourceFormatter.FullLineCommentDelimiter + // string.Format(Properties.Resources.GENERATED_FOR_VERSION, // "cc65", mAsmVersion.ToString())); //} else { // OutputLine(SourceFormatter.FullLineCommentDelimiter + // string.Format(Properties.Resources.GENERATED_FOR_LATEST, "cc65")); //} OutputLine(SourceFormatter.FullLineCommentDelimiter + string.Format(Res.Strings.GENERATED_FOR_VERSION_FMT, "cc65", V2_18, AsmCc65.OPTIONS + " -C " + Path.GetFileName(cfgName))); } GenCommon.Generate(this, sw, worker); } mOutStream = null; return(pathNames); }
// IGenerator public List <string> GenerateSource(BackgroundWorker worker) { List <string> pathNames = new List <string>(1); string fileName = mFileNameBase + ASM_FILE_SUFFIX; string pathName = Path.Combine(mWorkDirectory, fileName); pathNames.Add(pathName); Formatter.FormatConfig config = new Formatter.FormatConfig(); GenCommon.ConfigureFormatterFromSettings(Settings, ref config); SetFormatConfigValues(ref config); // Configure delimiters for single-character operands. Formatter.DelimiterSet charDelimSet = new Formatter.DelimiterSet(); charDelimSet.Set(CharEncoding.Encoding.C64Petscii, Formatter.SINGLE_QUOTE_DELIM); charDelimSet.Set(CharEncoding.Encoding.C64ScreenCode, Formatter.SINGLE_QUOTE_DELIM); charDelimSet.Set(CharEncoding.Encoding.Ascii, Formatter.SINGLE_QUOTE_DELIM); charDelimSet.Set(CharEncoding.Encoding.HighAscii, new Formatter.DelimiterDef(string.Empty, '\'', '\'', " | $80")); config.mCharDelimiters = charDelimSet; SourceFormatter = new Formatter(config); string msg = string.Format(Res.Strings.PROGRESS_GENERATING_FMT, pathName); worker.ReportProgress(0, msg); mLocalizer = new LabelLocalizer(Project); mLocalizer.LocalPrefix = "_"; mLocalizer.QuirkNoOpcodeMnemonics = true; mLocalizer.Analyze(); // Use UTF-8 encoding, without a byte-order mark. using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { mOutStream = sw; if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { OutputLine(SourceFormatter.FullLineCommentDelimiter + string.Format(Res.Strings.GENERATED_FOR_VERSION_FMT, "64tass", V1_53, AsmTass64.OPTIONS)); } GenCommon.Generate(this, sw, worker); if (mNeedHereOp) { OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(HERE_PSEUDO_OP), string.Empty, string.Empty); } } mOutStream = null; return(pathNames); }
// IGenerator; executes on background thread public List <string> GenerateSource(BackgroundWorker worker) { List <string> pathNames = new List <string>(1); string fileName = mFileNameBase + ASM_FILE_SUFFIX; string pathName = Path.Combine(mWorkDirectory, fileName); pathNames.Add(pathName); Formatter.FormatConfig config = new Formatter.FormatConfig(); GenCommon.ConfigureFormatterFromSettings(Settings, ref config); config.mForceAbsOpcodeSuffix = ":"; config.mForceLongOpcodeSuffix = "l"; config.mForceAbsOperandPrefix = string.Empty; config.mForceLongOperandPrefix = string.Empty; config.mEndOfLineCommentDelimiter = ";"; config.mFullLineCommentDelimiterBase = ";"; config.mBoxLineCommentDelimiter = string.Empty; config.mAllowHighAsciiCharConst = true; config.mExpressionMode = Formatter.FormatConfig.ExpressionMode.Merlin; SourceFormatter = new Formatter(config); string msg = string.Format(Properties.Resources.PROGRESS_GENERATING_FMT, pathName); worker.ReportProgress(0, msg); mLocalizer = new LabelLocalizer(Project); if (!Settings.GetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false)) { mLocalizer.LocalPrefix = ":"; mLocalizer.Analyze(); } // Use UTF-8 encoding, without a byte-order mark. using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { mOutStream = sw; if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { // No version-specific stuff yet. We're generating code for v1.0. OutputLine(SourceFormatter.FullLineCommentDelimiter + string.Format(Properties.Resources.GENERATED_FOR_VERSION, "Merlin 32", new CommonUtil.Version(1, 0))); } GenCommon.Generate(this, sw, worker); } mOutStream = null; return(pathNames); }
// IGenerator public List <string> GenerateSource(BackgroundWorker worker) { List <string> pathNames = new List <string>(1); string fileName = mFileNameBase + ASM_FILE_SUFFIX; string pathName = Path.Combine(mWorkDirectory, fileName); pathNames.Add(pathName); Formatter.FormatConfig config = new Formatter.FormatConfig(); GenCommon.ConfigureFormatterFromSettings(Settings, ref config); SetFormatConfigValues(ref config); SourceFormatter = new Formatter(config); string msg = string.Format(Properties.Resources.PROGRESS_GENERATING_FMT, pathName); worker.ReportProgress(0, msg); mLocalizer = new LabelLocalizer(Project); if (!Settings.GetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false)) { mLocalizer.LocalPrefix = "_"; mLocalizer.Analyze(); } mLocalizer.MaskLeadingUnderscores(); // Use UTF-8 encoding, without a byte-order mark. using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { mOutStream = sw; if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { OutputLine(SourceFormatter.FullLineCommentDelimiter + string.Format(Properties.Resources.GENERATED_FOR_VERSION, "64tass", V1_53, AsmTass64.OPTIONS)); } GenCommon.Generate(this, sw, worker); if (mNeedHereOp) { OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(HERE_PSEUDO_OP), string.Empty, string.Empty); } } mOutStream = null; return(pathNames); }
// IGenerator public GenerationResults GenerateSource(BackgroundWorker worker) { List <string> pathNames = new List <string>(1); string pathName = Path.Combine(mWorkDirectory, mFileNameBase + ASM_FILE_SUFFIX); pathNames.Add(pathName); string cfgName = Path.Combine(mWorkDirectory, mFileNameBase + CFG_FILE_SUFFIX); pathNames.Add(cfgName); Formatter.FormatConfig config = new Formatter.FormatConfig(); GenCommon.ConfigureFormatterFromSettings(Settings, ref config); SetFormatConfigValues(ref config); SourceFormatter = new Formatter(config); string msg = string.Format(Res.Strings.PROGRESS_GENERATING_FMT, pathName); worker.ReportProgress(0, msg); mLocalizer = new LabelLocalizer(Project); mLocalizer.LocalPrefix = "@"; mLocalizer.QuirkVariablesEndScope = true; // https://github.com/cc65/cc65/issues/938 mLocalizer.QuirkNoOpcodeMnemonics = true; mLocalizer.Analyze(); // Use UTF-8 encoding, without a byte-order mark. using (StreamWriter sw = new StreamWriter(cfgName, false, new UTF8Encoding(false))) { GenerateLinkerScript(sw); } using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { mOutStream = sw; if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { OutputLine(SourceFormatter.FullLineCommentDelimiter + string.Format(Res.Strings.GENERATED_FOR_VERSION_FMT, "cc65", mAsmVersion, AsmCc65.OPTIONS + " -C " + Path.GetFileName(cfgName))); } GenCommon.Generate(this, sw, worker); } mOutStream = null; return(new GenerationResults(pathNames, string.Empty)); }
// IGenerator; executes on background thread public GenerationResults GenerateSource(BackgroundWorker worker) { List <string> pathNames = new List <string>(1); string fileName = mFileNameBase + ASM_FILE_SUFFIX; string pathName = Path.Combine(mWorkDirectory, fileName); pathNames.Add(pathName); Formatter.FormatConfig config = new Formatter.FormatConfig(); GenCommon.ConfigureFormatterFromSettings(Settings, ref config); SetFormatConfigValues(ref config); SourceFormatter = new Formatter(config); string msg = string.Format(Res.Strings.PROGRESS_GENERATING_FMT, pathName); worker.ReportProgress(0, msg); mLocalizer = new LabelLocalizer(Project); mLocalizer.LocalPrefix = ":"; // don't need to set QuirkNoOpcodeMnemonics mLocalizer.Analyze(); // Use UTF-8 encoding, without a byte-order mark. using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { mOutStream = sw; if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { // No version-specific stuff yet. We're generating code for v1.0. OutputLine(SourceFormatter.FullLineCommentDelimiter + string.Format(Res.Strings.GENERATED_FOR_VERSION_FMT, "Merlin 32", new CommonUtil.Version(1, 0), string.Empty)); } GenCommon.Generate(this, sw, worker); } mOutStream = null; return(new GenerationResults(pathNames, string.Empty)); }
// IGenerator public void OutputDataOp(int offset) { Formatter formatter = SourceFormatter; byte[] data = Project.FileData; Anattrib attr = Project.GetAnattrib(offset); string labelStr = string.Empty; if (attr.Symbol != null) { labelStr = mLocalizer.ConvLabel(attr.Symbol.Label); } string commentStr = SourceFormatter.FormatEolComment(Project.Comments[offset]); string opcodeStr, operandStr; FormatDescriptor dfd = attr.DataDescriptor; Debug.Assert(dfd != null); int length = dfd.Length; Debug.Assert(length > 0); bool multiLine = false; switch (dfd.FormatType) { case FormatDescriptor.Type.Default: if (length != 1) { Debug.Assert(false); length = 1; } opcodeStr = sDataOpNames.DefineData1; int operand = RawData.GetWord(data, offset, length, false); operandStr = formatter.FormatHexValue(operand, length * 2); break; case FormatDescriptor.Type.NumericLE: opcodeStr = sDataOpNames.GetDefineData(length); operand = RawData.GetWord(data, offset, length, false); UpdateCharacterEncoding(dfd); operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable, mLocalizer.LabelMap, dfd, operand, length, PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix); break; case FormatDescriptor.Type.NumericBE: opcodeStr = sDataOpNames.GetDefineBigData(length); if ((string.IsNullOrEmpty(opcodeStr))) { // Nothing defined, output as comma-separated single-byte values. GenerateShortSequence(offset, length, out opcodeStr, out operandStr); } else { UpdateCharacterEncoding(dfd); operand = RawData.GetWord(data, offset, length, true); operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable, mLocalizer.LabelMap, dfd, operand, length, PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix); } break; case FormatDescriptor.Type.Fill: opcodeStr = sDataOpNames.Fill; operandStr = length + "," + formatter.FormatHexValue(data[offset], 2); break; case FormatDescriptor.Type.Dense: multiLine = true; opcodeStr = operandStr = null; OutputDenseHex(offset, length, labelStr, commentStr); break; case FormatDescriptor.Type.Junk: int fillVal = Helper.CheckRangeHoldsSingleValue(data, offset, length); if (fillVal >= 0 && GenCommon.CheckJunkAlign(offset, dfd, Project.AddrMap)) { // .align <expression>[, <fill>] opcodeStr = sDataOpNames.Align; int alignVal = 1 << FormatDescriptor.AlignmentToPower(dfd.FormatSubType); operandStr = alignVal.ToString() + "," + formatter.FormatHexValue(fillVal, 2); } else if (fillVal >= 0) { // treat same as Fill opcodeStr = sDataOpNames.Fill; operandStr = length + "," + formatter.FormatHexValue(fillVal, 2); } else { // treat same as Dense multiLine = true; opcodeStr = operandStr = null; OutputDenseHex(offset, length, labelStr, commentStr); } break; case FormatDescriptor.Type.StringGeneric: case FormatDescriptor.Type.StringReverse: case FormatDescriptor.Type.StringNullTerm: case FormatDescriptor.Type.StringL8: case FormatDescriptor.Type.StringL16: case FormatDescriptor.Type.StringDci: multiLine = true; opcodeStr = operandStr = null; OutputString(offset, labelStr, commentStr); break; default: opcodeStr = "???"; operandStr = "***"; break; } if (!multiLine) { opcodeStr = formatter.FormatPseudoOp(opcodeStr); OutputLine(labelStr, opcodeStr, operandStr, commentStr); } }
// IGenerator public GenerationResults GenerateSource(BackgroundWorker worker) { List <string> pathNames = new List <string>(1); string fileName = mFileNameBase + ASM_FILE_SUFFIX; string pathName = Path.Combine(mWorkDirectory, fileName); pathNames.Add(pathName); Formatter.FormatConfig config = new Formatter.FormatConfig(); GenCommon.ConfigureFormatterFromSettings(Settings, ref config); SetFormatConfigValues(ref config); SourceFormatter = new Formatter(config); string msg = string.Format(Res.Strings.PROGRESS_GENERATING_FMT, pathName); worker.ReportProgress(0, msg); mLocalizer = new LabelLocalizer(Project); // While '.' labels are limited to the current zone, '@' labels are visible // between global labels. (This is poorly documented.) mLocalizer.LocalPrefix = "@"; mLocalizer.QuirkNoOpcodeMnemonics = true; mLocalizer.ReservedWords = new List <string>() { "NOT" }; mLocalizer.Analyze(); mPcDepth = 0; mFirstIsOpen = true; // Use UTF-8 encoding, without a byte-order mark. using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { mOutStream = sw; if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { OutputLine(SourceFormatter.FullLineCommentDelimiter + string.Format(Res.Strings.GENERATED_FOR_VERSION_FMT, "acme", mAsmVersion, AsmAcme.OPTIONS)); } if (HasNonZeroBankCode()) { // don't try OutputLine(SourceFormatter.FullLineCommentDelimiter + "ACME can't handle 65816 code that lives outside bank zero"); int firstAddr = Project.AddrMap.OffsetToAddress(0); AddressMap.AddressRegion fakeRegion = new AddressMap.AddressRegion(0, Project.FileData.Length, firstAddr); OutputArDirective(new AddressMap.AddressChange(true, 0, firstAddr, fakeRegion, true)); OutputDenseHex(0, Project.FileData.Length, string.Empty, string.Empty); OutputArDirective(new AddressMap.AddressChange(false, 0, firstAddr, fakeRegion, true)); } else { GenCommon.Generate(this, sw, worker); } } mOutStream = null; return(new GenerationResults(pathNames, string.Empty)); }
// IGenerator public void Configure(DisasmProject project, string workDirectory, string fileNameBase, AssemblerVersion asmVersion, AppSettings settings) { Debug.Assert(project != null); Debug.Assert(!string.IsNullOrEmpty(workDirectory)); Debug.Assert(!string.IsNullOrEmpty(fileNameBase)); Project = project; Quirks = new AssemblerQuirks(); if (asmVersion != null) { mAsmVersion = asmVersion.Version; // Use the actual version. } else { mAsmVersion = V1_56; // No assembler installed, use default. } Quirks.StackIntOperandIsImmediate = true; Quirks.LeadingUnderscoreSpecial = true; Quirks.Need24BitsForAbsPBR = true; Quirks.BitNumberIsArg = true; Quirks.BankZeroAbsPBRRestrict = true; mWorkDirectory = workDirectory; mFileNameBase = fileNameBase; Settings = settings; mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false); AssemblerConfig config = AssemblerConfig.GetConfig(settings, AssemblerInfo.Id.Tass64); mColumnWidths = (int[])config.ColumnWidths.Clone(); // 64tass emulates a loader on a 64K system. The address you specify with // "* = <addr>" tells the loader where the code lives. If the project runs off the // end of memory, you get a warning message and an output file that has the last // part as the first part, because the loader wraps around. // // If (start_addr + total_len) doesn't fit without wrapping, we want to start // the code with "* = 0" (or omit it entirely) and use ".logical" for the first. // chunk. This allows us to generate the full 64K. Note that 65816 code that // starts outside bank 0 will always fail this test. // // Thus there are two modes: "loadable" and "streamable". We could output everything // as streamable but that's kind of ugly and prevents the PRG optimization. // // If the file has more than 64K of data in it, we need to add "--long-address" to // the command-line arguments. // Get start address. If this is a PRG file, the start address is the address // of offset +000002. bool hasPrgHeader = GenCommon.HasPrgHeader(project); int offAdj = hasPrgHeader ? 2 : 0; int startAddr = project.AddrMap.OffsetToAddress(offAdj); if (startAddr + project.FileDataLength - offAdj > 65536) { // Does not fit into memory at load address. mOutputMode = OutputMode.Streamable; mHasPrgHeader = false; } else { mOutputMode = OutputMode.Loadable; mHasPrgHeader = hasPrgHeader; } //Debug.WriteLine("startAddr=$" + startAddr.ToString("x6") + // " outputMode=" + mOutputMode + " hasPrg=" + mHasPrgHeader); }
// IGenerator public void OutputDataOp(int offset) { Formatter formatter = SourceFormatter; byte[] data = Project.FileData; Anattrib attr = Project.GetAnattrib(offset); string labelStr = string.Empty; if (attr.Symbol != null) { labelStr = mLocalizer.ConvLabel(attr.Symbol.Label); } string commentStr = SourceFormatter.FormatEolComment(Project.Comments[offset]); string opcodeStr, operandStr; FormatDescriptor dfd = attr.DataDescriptor; Debug.Assert(dfd != null); int length = dfd.Length; Debug.Assert(length > 0); bool multiLine = false; switch (dfd.FormatType) { case FormatDescriptor.Type.Default: if (length != 1) { Debug.Assert(false); length = 1; } opcodeStr = sDataOpNames.DefineData1; int operand = RawData.GetWord(data, offset, length, false); operandStr = formatter.FormatHexValue(operand, length * 2); break; case FormatDescriptor.Type.NumericLE: opcodeStr = sDataOpNames.GetDefineData(length); operand = RawData.GetWord(data, offset, length, false); if (length == 1 && dfd.IsStringOrCharacter && ((operand & 0x7f) == '{' || (operand & 0x7f) == '}')) { // Merlin32 can't handle "DFB '{'", so just output hex. operandStr = formatter.FormatHexValue(operand, length * 2); } else { operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable, mLocalizer.LabelMap, dfd, operand, length, PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix); } break; case FormatDescriptor.Type.NumericBE: opcodeStr = sDataOpNames.GetDefineBigData(length); if ((string.IsNullOrEmpty(opcodeStr))) { // Nothing defined, output as comma-separated single-byte values. GenerateShortSequence(offset, length, out opcodeStr, out operandStr); } else { operand = RawData.GetWord(data, offset, length, true); operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable, mLocalizer.LabelMap, dfd, operand, length, PseudoOp.FormatNumericOpFlags.OmitLabelPrefixSuffix); } break; case FormatDescriptor.Type.Fill: opcodeStr = sDataOpNames.Fill; if (data[offset] == 0) { operandStr = length.ToString(); } else { operandStr = length + "," + formatter.FormatHexValue(data[offset], 2); } break; case FormatDescriptor.Type.Dense: multiLine = true; opcodeStr = operandStr = null; OutputDenseHex(offset, length, labelStr, commentStr); break; case FormatDescriptor.Type.Uninit: case FormatDescriptor.Type.Junk: int fillVal = Helper.CheckRangeHoldsSingleValue(data, offset, length); if (fillVal >= 0) { opcodeStr = sDataOpNames.Fill; if (dfd.FormatSubType == FormatDescriptor.SubType.Align256 && GenCommon.CheckJunkAlign(offset, dfd, Project.AddrMap)) { // special syntax for page alignment if (fillVal == 0) { operandStr = "\\"; } else { operandStr = "\\," + formatter.FormatHexValue(fillVal, 2); } } else if (length == 1 && fillVal != 0x00) { // Single-byte HEX looks better than "ds 1,$xx", and will match up // with adjacent multi-byte junk/uninit. multiLine = true; opcodeStr = operandStr = null; OutputDenseHex(offset, length, labelStr, commentStr); } else { if (fillVal == 0) { operandStr = length.ToString(); } else { operandStr = length + "," + formatter.FormatHexValue(fillVal, 2); } } } else { // treat same as Dense multiLine = true; opcodeStr = operandStr = null; OutputDenseHex(offset, length, labelStr, commentStr); } break; case FormatDescriptor.Type.StringGeneric: case FormatDescriptor.Type.StringReverse: case FormatDescriptor.Type.StringNullTerm: case FormatDescriptor.Type.StringL8: case FormatDescriptor.Type.StringL16: case FormatDescriptor.Type.StringDci: multiLine = true; opcodeStr = operandStr = null; OutputString(offset, labelStr, commentStr); break; default: opcodeStr = "???"; operandStr = "***"; break; } if (!multiLine) { opcodeStr = formatter.FormatPseudoOp(opcodeStr); OutputLine(labelStr, opcodeStr, operandStr, commentStr); } }