Beispiel #1
0
        // 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);
        }
Beispiel #2
0
        // 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);
        }
Beispiel #3
0
        // 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);
        }
Beispiel #4
0
        // 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));
        }
Beispiel #5
0
        // 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);
        }
Beispiel #6
0
        // 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);
        }
Beispiel #7
0
        // 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);
        }
Beispiel #8
0
        // 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);
        }
Beispiel #9
0
        // 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));
        }
Beispiel #10
0
        // 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));
        }
Beispiel #11
0
        // 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);
            }
        }
Beispiel #12
0
        // 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));
        }
Beispiel #13
0
        // 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);
        }
Beispiel #14
0
        // 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);
            }
        }