From bde4f2ed0738bfd0f1ae08eeecb933abc80f219e Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Sun, 4 May 2025 07:58:49 -0700 Subject: [PATCH] Tweak Merlin32 generator Merlin32 v1.2 requires DSK and TYP directives. We now add these if version 1.2 is detected. (Earlier versions of Merlin32 accept them, so at some point we may just want to output them always.) The version-parsing code has been updated to deal with pre-release version strings. --- SourceGen/AsmGen/AsmMerlin32.cs | 37 ++++++++++++++++++++------------- SourceGen/Tests/GenTest.cs | 3 ++- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/SourceGen/AsmGen/AsmMerlin32.cs b/SourceGen/AsmGen/AsmMerlin32.cs index fec43ca..b3a6d2f 100644 --- a/SourceGen/AsmGen/AsmMerlin32.cs +++ b/SourceGen/AsmGen/AsmMerlin32.cs @@ -19,6 +19,7 @@ using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Text; +using System.Text.RegularExpressions; using Asm65; using CommonUtil; @@ -32,6 +33,7 @@ namespace SourceGen.AsmGen { /// public class GenMerlin32 : IGenerator { private const string ASM_FILE_SUFFIX = "_merlin32.S"; // must start with underscore + private const string OUT_FILE_SUFFIX = "_merlin32"; // IGenerator public DisasmProject Project { get; private set; } @@ -115,6 +117,7 @@ namespace SourceGen.AsmGen { // Interesting versions. private static CommonUtil.Version V1_0 = new CommonUtil.Version(1, 0); + private static CommonUtil.Version V1_2 = new CommonUtil.Version(1, 2); // Pseudo-op string constants. @@ -251,6 +254,17 @@ namespace SourceGen.AsmGen { return new GenerationResults(pathNames, string.Empty, mBinaryIncludes); } + // IGenerator + public void OutputAsmConfig() { + // Merlin v1.2 requires TYP and DSK directives. + if (mAsmVersion >= V1_2) { + OutputLine(string.Empty, SourceFormatter.FormatPseudoOp("DSK"), + mFileNameBase + OUT_FILE_SUFFIX, string.Empty); + OutputLine(string.Empty, SourceFormatter.FormatPseudoOp("TYP"), + "BIN", string.Empty); + } + } + // IGenerator public void OutputDataOp(int offset) { Formatter formatter = SourceFormatter; @@ -498,11 +512,6 @@ namespace SourceGen.AsmGen { operand = sb.ToString(); } - // IGenerator - public void OutputAsmConfig() { - // nothing to do (though we could emit "xc off" for 6502) - } - // IGenerator public void OutputEquDirective(string name, string valueStr, string comment) { OutputLine(name, SourceFormatter.FormatPseudoOp(sDataOpNames.EquDirective), @@ -831,6 +840,12 @@ namespace SourceGen.AsmGen { return new AssemblerConfig(string.Empty, new int[] { 9, 6, 11, 74 }); } + // Stdout: "C:\Src\WorkBench\Merlin32.exe v 1.0, (c) Brutal Deluxe ..." + // "C:\Src\WorkBench\Merlin32.exe v 1.2 beta 1, (c) Brutal Deluxe ..." + // Other platforms may not have the ".exe". Start at first occurrence of " v ". + private static string sVersionPattern = @" v (\d.\d)( [^,]+)?,"; + private static Regex sVersionRegex = new Regex(sVersionPattern); + // IAssembler public AssemblerVersion QueryVersion() { AssemblerConfig config = @@ -846,20 +861,14 @@ namespace SourceGen.AsmGen { return null; } - // Stdout: "C:\Src\WorkBench\Merlin32.exe v 1.0, (c) Brutal Deluxe ..." - // Other platforms may not have the ".exe". Find first occurrence of " v ". - - const string PREFIX = " v "; // not expecting this to appear in the path string str = cmd.Stdout; - int start = str.IndexOf(PREFIX); - int end = (start < 0) ? -1 : str.IndexOf(',', start); + MatchCollection matches = sVersionRegex.Matches(str); - if (start < 0 || end < 0 || start + PREFIX.Length >= end) { + if (matches.Count != 1) { Debug.WriteLine("Couldn't find version in " + str); return null; } - start += PREFIX.Length; - string versionStr = str.Substring(start, end - start); + string versionStr = matches[0].Groups[1].Value; CommonUtil.Version version = CommonUtil.Version.Parse(versionStr); if (!version.IsValid) { return null; diff --git a/SourceGen/Tests/GenTest.cs b/SourceGen/Tests/GenTest.cs index 4c6c42b..c39b947 100644 --- a/SourceGen/Tests/GenTest.cs +++ b/SourceGen/Tests/GenTest.cs @@ -417,7 +417,8 @@ namespace SourceGen.Tests { while (iter.MoveNext()) { AssemblerInfo info = iter.Current; AssemblerVersion version = AssemblerVersionCache.GetVersion(info.AssemblerId); - ReportProgress(" " + info.Name + " v" + version.VersionStr); + ReportProgress(" " + info.Name + " v" + + (version != null ? version.VersionStr : "UNAVAILABLE")); } ReportProgress("\n"); }