mirror of
https://github.com/fadden/6502bench.git
synced 2024-06-11 17:29:29 +00:00
Add option to put labels on separate lines
We currently have two options for assembly code output, selected by a checkbox in the application settings: always put labels on the same lines as the instruction or data operand, or split the labels onto their own line if they were wider than the label text field. This change adds a third option, which puts labels on their own line whenever possible. Assemblers don't generally allow this for variable assignment pseudo-ops like "foo = $1000", but it's accepted for most other situations. This is a cosmetic change to the output, and will not affect the generated code. The old true/false app setting will be disregarded. "Split if too long" will be used by default. Added test 20280-label-placement to exercise the "split whenever allowed" behavior. The "export" function has a similar option that has not been updated (for no particular reason other than laziness). Also, simplified the app settings GetEnum / SetEnum calls, which can infer the enumerated type from the arguments. This should not impact behavior.
This commit is contained in:
parent
e425237783
commit
4322a0c231
|
@ -42,10 +42,10 @@ namespace CommonUtil {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Usage:
|
/// Usage:
|
||||||
/// AppDomain.CurrentDomain.UnhandledException +=
|
/// <code>AppDomain.CurrentDomain.UnhandledException +=
|
||||||
/// new UnhandledExceptionEventHandler(CommonUtil.Misc.CrashReporter);
|
/// new UnhandledExceptionEventHandler(CommonUtil.Misc.CrashReporter);</code>
|
||||||
///
|
///
|
||||||
/// Thanks: https://stackoverflow.com/a/21308327/294248
|
/// Thanks: <see href="https://stackoverflow.com/a/21308327/294248"/>.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static void CrashReporter(object sender, UnhandledExceptionEventArgs e) {
|
public static void CrashReporter(object sender, UnhandledExceptionEventArgs e) {
|
||||||
const string CRASH_PATH = @"CrashLog.txt";
|
const string CRASH_PATH = @"CrashLog.txt";
|
||||||
|
@ -80,7 +80,7 @@ namespace CommonUtil {
|
||||||
/// faster than setting array elements individually.
|
/// faster than setting array elements individually.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// From https://stackoverflow.com/a/18659408/294248
|
/// From <see href="https://stackoverflow.com/a/18659408/294248"/>.
|
||||||
///
|
///
|
||||||
/// Invokes Array.Copy() on overlapping elements. Other approaches involve using
|
/// Invokes Array.Copy() on overlapping elements. Other approaches involve using
|
||||||
/// Buffer.BlockCopy or unsafe code. Apparently .NET Core has an Array.Fill(), but
|
/// Buffer.BlockCopy or unsafe code. Apparently .NET Core has an Array.Fill(), but
|
||||||
|
|
|
@ -124,7 +124,7 @@ namespace SourceGen {
|
||||||
// Source generation settings.
|
// Source generation settings.
|
||||||
public const string SRCGEN_DEFAULT_ASM = "srcgen-default-asm";
|
public const string SRCGEN_DEFAULT_ASM = "srcgen-default-asm";
|
||||||
public const string SRCGEN_ADD_IDENT_COMMENT = "srcgen-add-ident-comment";
|
public const string SRCGEN_ADD_IDENT_COMMENT = "srcgen-add-ident-comment";
|
||||||
public const string SRCGEN_LONG_LABEL_NEW_LINE = "srcgen-long-label-new-line";
|
public const string SRCGEN_LABEL_NEW_LINE = "srcgen-label-new-line";
|
||||||
public const string SRCGEN_SHOW_CYCLE_COUNTS = "srcgen-show-cycle-counts";
|
public const string SRCGEN_SHOW_CYCLE_COUNTS = "srcgen-show-cycle-counts";
|
||||||
|
|
||||||
// Label file generation settings.
|
// Label file generation settings.
|
||||||
|
@ -291,21 +291,20 @@ namespace SourceGen {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves an enumerated value setting.
|
/// Retrieves an enumerated value setting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Enumerated type.</typeparam>
|
||||||
/// <param name="name">Setting name.</param>
|
/// <param name="name">Setting name.</param>
|
||||||
/// <param name="enumType">Enum type that the value is part of.</param>
|
|
||||||
/// <param name="defaultValue">Setting default value.</param>
|
/// <param name="defaultValue">Setting default value.</param>
|
||||||
/// <returns>The value found, or the default value if no setting with the specified
|
/// <returns>The value found, or the default value if no setting with the specified
|
||||||
/// name exists, or the stored value is not a member of the specified enumerated
|
/// name exists, or the stored value is not a member of the enumeration.</returns>
|
||||||
/// type.</returns>
|
public T GetEnum<T>(string name, T defaultValue) {
|
||||||
public int GetEnum(string name, Type enumType, int defaultValue) {
|
|
||||||
if (!mSettings.TryGetValue(name, out string valueStr)) {
|
if (!mSettings.TryGetValue(name, out string valueStr)) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
object o = Enum.Parse(enumType, valueStr);
|
object o = Enum.Parse(typeof(T), valueStr);
|
||||||
return (int)o;
|
return (T)o;
|
||||||
} catch (ArgumentException ae) {
|
} catch (ArgumentException ae) {
|
||||||
Debug.WriteLine("Failed to parse " + valueStr + " (enum " + enumType + "): " +
|
Debug.WriteLine("Failed to parse '" + valueStr + "' (enum " + typeof(T) + "): " +
|
||||||
ae.Message);
|
ae.Message);
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
@ -314,14 +313,20 @@ namespace SourceGen {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets an enumerated setting.
|
/// Sets an enumerated setting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The value is output to the settings file as a string, rather than an integer, allowing
|
||||||
|
/// the correct handling even if the enumerated values are renumbered.
|
||||||
|
/// </remarks>
|
||||||
|
/// <typeparam name="T">Enumerated type.</typeparam>
|
||||||
/// <param name="name">Setting name.</param>
|
/// <param name="name">Setting name.</param>
|
||||||
/// <param name="enumType">Enum type.</param>
|
|
||||||
/// <param name="value">Setting value (integer enum index).</param>
|
/// <param name="value">Setting value (integer enum index).</param>
|
||||||
public void SetEnum(string name, Type enumType, int value) {
|
public void SetEnum<T>(string name, T value) {
|
||||||
string newVal = Enum.GetName(enumType, value);
|
if (value == null) {
|
||||||
|
throw new NotImplementedException("Can't handle a null-valued enum type");
|
||||||
|
}
|
||||||
|
string newVal = Enum.GetName(typeof(T), value);
|
||||||
if (newVal == null) {
|
if (newVal == null) {
|
||||||
// Shouldn't be possible if an enum value of the correct type is passed in.
|
Debug.WriteLine("Unable to get enum name type=" + typeof(T) + " value=" + value);
|
||||||
Debug.WriteLine("Unable to get enum name type=" + enumType + " value=" + value);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!mSettings.TryGetValue(name, out string oldValue) || oldValue != newVal) {
|
if (!mSettings.TryGetValue(name, out string oldValue) || oldValue != newVal) {
|
||||||
|
|
|
@ -62,9 +62,9 @@ namespace SourceGen.AsmGen {
|
||||||
private string mWorkDirectory;
|
private string mWorkDirectory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If set, long labels get their own line.
|
/// Influences whether labels are put on their own line.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool mLongLabelNewLine;
|
private GenCommon.LabelPlacement mLabelNewLine;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Output column widths.
|
/// Output column widths.
|
||||||
|
@ -198,7 +198,8 @@ namespace SourceGen.AsmGen {
|
||||||
mFileNameBase = fileNameBase;
|
mFileNameBase = fileNameBase;
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
|
|
||||||
mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false);
|
mLabelNewLine = Settings.GetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
GenCommon.LabelPlacement.SplitIfTooLong);
|
||||||
|
|
||||||
AssemblerConfig config = AssemblerConfig.GetConfig(settings,
|
AssemblerConfig config = AssemblerConfig.GetConfig(settings,
|
||||||
AssemblerInfo.Id.Acme);
|
AssemblerInfo.Id.Acme);
|
||||||
|
@ -667,7 +668,9 @@ namespace SourceGen.AsmGen {
|
||||||
!string.Equals(opcode, sDataOpNames.EquDirective,
|
!string.Equals(opcode, sDataOpNames.EquDirective,
|
||||||
StringComparison.InvariantCultureIgnoreCase)) {
|
StringComparison.InvariantCultureIgnoreCase)) {
|
||||||
|
|
||||||
if (mLongLabelNewLine && label.Length >= mColumnWidths[0]) {
|
if (mLabelNewLine == GenCommon.LabelPlacement.PreferSeparateLine ||
|
||||||
|
(mLabelNewLine == GenCommon.LabelPlacement.SplitIfTooLong &&
|
||||||
|
label.Length >= mColumnWidths[0])) {
|
||||||
mOutStream.WriteLine(label);
|
mOutStream.WriteLine(label);
|
||||||
label = string.Empty;
|
label = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,9 +57,9 @@ namespace SourceGen.AsmGen {
|
||||||
private string mWorkDirectory;
|
private string mWorkDirectory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If set, long labels get their own line.
|
/// Influences whether labels are put on their own line.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool mLongLabelNewLine;
|
private GenCommon.LabelPlacement mLabelNewLine;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Output column widths.
|
/// Output column widths.
|
||||||
|
@ -188,7 +188,8 @@ namespace SourceGen.AsmGen {
|
||||||
mFileNameBase = fileNameBase;
|
mFileNameBase = fileNameBase;
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
|
|
||||||
mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false);
|
mLabelNewLine = Settings.GetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
GenCommon.LabelPlacement.SplitIfTooLong);
|
||||||
|
|
||||||
AssemblerConfig config = AssemblerConfig.GetConfig(settings,
|
AssemblerConfig config = AssemblerConfig.GetConfig(settings,
|
||||||
AssemblerInfo.Id.Cc65);
|
AssemblerInfo.Id.Cc65);
|
||||||
|
@ -659,7 +660,9 @@ namespace SourceGen.AsmGen {
|
||||||
StringComparison.InvariantCultureIgnoreCase)) {
|
StringComparison.InvariantCultureIgnoreCase)) {
|
||||||
label += ':';
|
label += ':';
|
||||||
|
|
||||||
if (mLongLabelNewLine && label.Length >= mColumnWidths[0]) {
|
if (mLabelNewLine == GenCommon.LabelPlacement.PreferSeparateLine ||
|
||||||
|
(mLabelNewLine == GenCommon.LabelPlacement.SplitIfTooLong &&
|
||||||
|
label.Length >= mColumnWidths[0])) {
|
||||||
mOutStream.WriteLine(label);
|
mOutStream.WriteLine(label);
|
||||||
label = string.Empty;
|
label = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,9 +57,9 @@ namespace SourceGen.AsmGen {
|
||||||
private string mWorkDirectory;
|
private string mWorkDirectory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If set, long labels get their own line.
|
/// Influences whether labels are put on their own line.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool mLongLabelNewLine;
|
private GenCommon.LabelPlacement mLabelNewLine;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Output column widths.
|
/// Output column widths.
|
||||||
|
@ -174,7 +174,8 @@ namespace SourceGen.AsmGen {
|
||||||
mFileNameBase = fileNameBase;
|
mFileNameBase = fileNameBase;
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
|
|
||||||
mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false);
|
mLabelNewLine = Settings.GetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
GenCommon.LabelPlacement.SplitIfTooLong);
|
||||||
|
|
||||||
AssemblerConfig config = AssemblerConfig.GetConfig(settings,
|
AssemblerConfig config = AssemblerConfig.GetConfig(settings,
|
||||||
AssemblerInfo.Id.Merlin32);
|
AssemblerInfo.Id.Merlin32);
|
||||||
|
@ -606,11 +607,14 @@ namespace SourceGen.AsmGen {
|
||||||
// IGenerator
|
// IGenerator
|
||||||
public void OutputLine(string label, string opcode, string operand, string comment) {
|
public void OutputLine(string label, string opcode, string operand, string comment) {
|
||||||
// Split long label, but not on EQU directives (confuses the assembler).
|
// Split long label, but not on EQU directives (confuses the assembler).
|
||||||
if (mLongLabelNewLine && label.Length >= mColumnWidths[0] &&
|
if (!string.IsNullOrEmpty(label) && !string.Equals(opcode, sDataOpNames.EquDirective,
|
||||||
!string.Equals(opcode, sDataOpNames.EquDirective,
|
|
||||||
StringComparison.InvariantCultureIgnoreCase)) {
|
StringComparison.InvariantCultureIgnoreCase)) {
|
||||||
mOutStream.WriteLine(label);
|
if (mLabelNewLine == GenCommon.LabelPlacement.PreferSeparateLine ||
|
||||||
label = string.Empty;
|
(mLabelNewLine == GenCommon.LabelPlacement.SplitIfTooLong &&
|
||||||
|
label.Length >= mColumnWidths[0])) {
|
||||||
|
mOutStream.WriteLine(label);
|
||||||
|
label = string.Empty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mLineBuilder.Clear();
|
mLineBuilder.Clear();
|
||||||
|
|
|
@ -73,9 +73,9 @@ namespace SourceGen.AsmGen {
|
||||||
private string mWorkDirectory;
|
private string mWorkDirectory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If set, long labels get their own line.
|
/// Influences whether labels are put on their own line.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool mLongLabelNewLine;
|
private GenCommon.LabelPlacement mLabelNewLine;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Output column widths.
|
/// Output column widths.
|
||||||
|
@ -201,7 +201,8 @@ namespace SourceGen.AsmGen {
|
||||||
mFileNameBase = fileNameBase;
|
mFileNameBase = fileNameBase;
|
||||||
Settings = settings;
|
Settings = settings;
|
||||||
|
|
||||||
mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false);
|
mLabelNewLine = Settings.GetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
GenCommon.LabelPlacement.SplitIfTooLong);
|
||||||
|
|
||||||
AssemblerConfig config = AssemblerConfig.GetConfig(settings,
|
AssemblerConfig config = AssemblerConfig.GetConfig(settings,
|
||||||
AssemblerInfo.Id.Tass64);
|
AssemblerInfo.Id.Tass64);
|
||||||
|
@ -777,7 +778,9 @@ namespace SourceGen.AsmGen {
|
||||||
!string.Equals(opcode, sDataOpNames.VarDirective,
|
!string.Equals(opcode, sDataOpNames.VarDirective,
|
||||||
StringComparison.InvariantCultureIgnoreCase)) {
|
StringComparison.InvariantCultureIgnoreCase)) {
|
||||||
|
|
||||||
if (mLongLabelNewLine && label.Length >= mColumnWidths[0]) {
|
if (mLabelNewLine == GenCommon.LabelPlacement.PreferSeparateLine ||
|
||||||
|
(mLabelNewLine == GenCommon.LabelPlacement.SplitIfTooLong &&
|
||||||
|
label.Length >= mColumnWidths[0])) {
|
||||||
mOutStream.WriteLine(label);
|
mOutStream.WriteLine(label);
|
||||||
label = string.Empty;
|
label = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,19 @@ using Asm65;
|
||||||
using CommonUtil;
|
using CommonUtil;
|
||||||
|
|
||||||
namespace SourceGen.AsmGen {
|
namespace SourceGen.AsmGen {
|
||||||
|
/// <summary>
|
||||||
|
/// Code common to all assembly source generators.
|
||||||
|
/// </summary>
|
||||||
public class GenCommon {
|
public class GenCommon {
|
||||||
|
public enum LabelPlacement {
|
||||||
|
Unknown = 0,
|
||||||
|
PreferSameLine,
|
||||||
|
SplitIfTooLong,
|
||||||
|
PreferSeparateLine,
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates assembly source.
|
/// Generates assembly source.
|
||||||
///
|
|
||||||
/// This code is common to all generators.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="gen">Reference to generator object (presumably the caller).</param>
|
/// <param name="gen">Reference to generator object (presumably the caller).</param>
|
||||||
/// <param name="sw">Text output sink.</param>
|
/// <param name="sw">Text output sink.</param>
|
||||||
|
|
|
@ -550,10 +550,8 @@ namespace SourceGen {
|
||||||
// but we're only doing this on the template file, which should be small.
|
// but we're only doing this on the template file, which should be small.
|
||||||
tmplStr = tmplStr.Replace("$ProjectName$", mProject.DataFileName);
|
tmplStr = tmplStr.Replace("$ProjectName$", mProject.DataFileName);
|
||||||
tmplStr = tmplStr.Replace("$AppVersion$", App.ProgramVersion.ToString());
|
tmplStr = tmplStr.Replace("$AppVersion$", App.ProgramVersion.ToString());
|
||||||
string expModeStr = ((Formatter.FormatConfig.ExpressionMode)
|
string expModeStr = AppSettings.Global.GetEnum(AppSettings.FMT_EXPRESSION_MODE,
|
||||||
AppSettings.Global.GetEnum(AppSettings.FMT_EXPRESSION_MODE,
|
Formatter.FormatConfig.ExpressionMode.Unknown).ToString();
|
||||||
typeof(Formatter.FormatConfig.ExpressionMode),
|
|
||||||
(int)Formatter.FormatConfig.ExpressionMode.Unknown)).ToString();
|
|
||||||
tmplStr = tmplStr.Replace("$ExpressionStyle$", expModeStr);
|
tmplStr = tmplStr.Replace("$ExpressionStyle$", expModeStr);
|
||||||
string dateStr = DateTime.Now.ToString("yyyy/MM/dd");
|
string dateStr = DateTime.Now.ToString("yyyy/MM/dd");
|
||||||
string timeStr = DateTime.Now.ToString("HH:mm:ss zzz");
|
string timeStr = DateTime.Now.ToString("HH:mm:ss zzz");
|
||||||
|
|
|
@ -345,7 +345,8 @@ namespace SourceGen {
|
||||||
settings.SetString(AppSettings.FMT_OPERAND_PREFIX_LONG, "f:");
|
settings.SetString(AppSettings.FMT_OPERAND_PREFIX_LONG, "f:");
|
||||||
|
|
||||||
settings.SetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, true);
|
settings.SetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, true);
|
||||||
settings.SetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, true);
|
settings.SetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
AsmGen.GenCommon.LabelPlacement.SplitIfTooLong);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
settings.SetBool(AppSettings.DEBUG_MENU_ENABLED, true);
|
settings.SetBool(AppSettings.DEBUG_MENU_ENABLED, true);
|
||||||
|
@ -1462,10 +1463,8 @@ namespace SourceGen {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClipLineFormat format = (ClipLineFormat)AppSettings.Global.GetEnum(
|
ClipLineFormat format = AppSettings.Global.GetEnum(AppSettings.CLIP_LINE_FORMAT,
|
||||||
AppSettings.CLIP_LINE_FORMAT,
|
ClipLineFormat.AssemblerSource);
|
||||||
typeof(ClipLineFormat),
|
|
||||||
(int)ClipLineFormat.AssemblerSource);
|
|
||||||
|
|
||||||
int[] rightWidths = new int[] { 16, 6, 16, 80 };
|
int[] rightWidths = new int[] { 16, 6, 16, 80 };
|
||||||
|
|
||||||
|
|
BIN
SourceGen/SGTestData/20280-label-placement
Normal file
BIN
SourceGen/SGTestData/20280-label-placement
Normal file
Binary file not shown.
175
SourceGen/SGTestData/20280-label-placement.dis65
Normal file
175
SourceGen/SGTestData/20280-label-placement.dis65
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
### 6502bench SourceGen dis65 v1.0 ###
|
||||||
|
{
|
||||||
|
"_ContentVersion":5,
|
||||||
|
"FileDataLength":25,
|
||||||
|
"FileDataCrc32":646072439,
|
||||||
|
"ProjectProps":{
|
||||||
|
"CpuName":"6502",
|
||||||
|
"IncludeUndocumentedInstr":false,
|
||||||
|
"TwoByteBrk":false,
|
||||||
|
"EntryFlags":32702671,
|
||||||
|
"AutoLabelStyle":"Simple",
|
||||||
|
"AnalysisParams":{
|
||||||
|
"AnalyzeUncategorizedData":true,
|
||||||
|
"DefaultTextScanMode":"LowHighAscii",
|
||||||
|
"MinCharsForString":4,
|
||||||
|
"SeekNearbyTargets":true,
|
||||||
|
"UseRelocData":false,
|
||||||
|
"SmartPlpHandling":false,
|
||||||
|
"SmartPlbHandling":true},
|
||||||
|
|
||||||
|
"PlatformSymbolFileIdentifiers":[],
|
||||||
|
"ExtensionScriptFileIdentifiers":[],
|
||||||
|
"ProjectSyms":{
|
||||||
|
"__ENABLE_ALL_LABEL_NEWLINE":{
|
||||||
|
"DataDescriptor":{
|
||||||
|
"Length":1,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Decimal",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
|
"Comment":"",
|
||||||
|
"HasWidth":false,
|
||||||
|
"Direction":"ReadWrite",
|
||||||
|
"MultiMask":null,
|
||||||
|
"Label":"__ENABLE_ALL_LABEL_NEWLINE",
|
||||||
|
"Value":1,
|
||||||
|
"Source":"Project",
|
||||||
|
"Type":"ExternalAddr",
|
||||||
|
"LabelAnno":"None"},
|
||||||
|
|
||||||
|
"shortnm":{
|
||||||
|
"DataDescriptor":{
|
||||||
|
"Length":1,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
|
"Comment":"short label",
|
||||||
|
"HasWidth":false,
|
||||||
|
"Direction":"ReadWrite",
|
||||||
|
"MultiMask":null,
|
||||||
|
"Label":"shortnm",
|
||||||
|
"Value":16384,
|
||||||
|
"Source":"Project",
|
||||||
|
"Type":"ExternalAddr",
|
||||||
|
"LabelAnno":"None"},
|
||||||
|
|
||||||
|
"SomewhatLongName":{
|
||||||
|
"DataDescriptor":{
|
||||||
|
"Length":1,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
|
"Comment":"somewhat longer label",
|
||||||
|
"HasWidth":false,
|
||||||
|
"Direction":"ReadWrite",
|
||||||
|
"MultiMask":null,
|
||||||
|
"Label":"SomewhatLongName",
|
||||||
|
"Value":16385,
|
||||||
|
"Source":"Project",
|
||||||
|
"Type":"ExternalAddr",
|
||||||
|
"LabelAnno":"None"}}},
|
||||||
|
|
||||||
|
"AddressMap":[{
|
||||||
|
"Offset":0,
|
||||||
|
"Addr":4096,
|
||||||
|
"Length":25,
|
||||||
|
"PreLabel":"",
|
||||||
|
"IsRelative":false}],
|
||||||
|
"TypeHints":[{
|
||||||
|
"Low":0,
|
||||||
|
"High":0,
|
||||||
|
"Hint":"Code"}],
|
||||||
|
"StatusFlagOverrides":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"Comments":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"LongComments":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"Notes":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"UserLabels":{
|
||||||
|
"9":{
|
||||||
|
"Label":"data",
|
||||||
|
"Value":4105,
|
||||||
|
"Source":"User",
|
||||||
|
"Type":"GlobalAddr",
|
||||||
|
"LabelAnno":"None"},
|
||||||
|
|
||||||
|
"20":{
|
||||||
|
"Label":"shortb",
|
||||||
|
"Value":4116,
|
||||||
|
"Source":"User",
|
||||||
|
"Type":"GlobalAddr",
|
||||||
|
"LabelAnno":"None"},
|
||||||
|
|
||||||
|
"10":{
|
||||||
|
"Label":"BranchTargetLongName",
|
||||||
|
"Value":4106,
|
||||||
|
"Source":"User",
|
||||||
|
"Type":"GlobalAddr",
|
||||||
|
"LabelAnno":"None"},
|
||||||
|
|
||||||
|
"24":{
|
||||||
|
"Label":"done",
|
||||||
|
"Value":4120,
|
||||||
|
"Source":"User",
|
||||||
|
"Type":"GlobalAddr",
|
||||||
|
"LabelAnno":"None"}},
|
||||||
|
|
||||||
|
"OperandFormats":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"LvTables":{
|
||||||
|
"10":{
|
||||||
|
"Variables":[{
|
||||||
|
"DataDescriptor":{
|
||||||
|
"Length":2,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
|
"Comment":"local var with short name",
|
||||||
|
"HasWidth":true,
|
||||||
|
"Direction":"ReadWrite",
|
||||||
|
"MultiMask":null,
|
||||||
|
"Label":"ptr",
|
||||||
|
"Value":0,
|
||||||
|
"Source":"Variable",
|
||||||
|
"Type":"ExternalAddr",
|
||||||
|
"LabelAnno":"None"},
|
||||||
|
|
||||||
|
{
|
||||||
|
"DataDescriptor":{
|
||||||
|
"Length":2,
|
||||||
|
"Format":"NumericLE",
|
||||||
|
"SubFormat":"Hex",
|
||||||
|
"SymbolRef":null},
|
||||||
|
|
||||||
|
"Comment":"local var with longer name",
|
||||||
|
"HasWidth":true,
|
||||||
|
"Direction":"ReadWrite",
|
||||||
|
"MultiMask":null,
|
||||||
|
"Label":"PointerWithLongName",
|
||||||
|
"Value":2,
|
||||||
|
"Source":"Variable",
|
||||||
|
"Type":"ExternalAddr",
|
||||||
|
"LabelAnno":"None"}],
|
||||||
|
"ClearPrevious":false}},
|
||||||
|
|
||||||
|
"Visualizations":[],
|
||||||
|
"VisualizationAnimations":[],
|
||||||
|
"VisualizationSets":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"RelocList":{
|
||||||
|
},
|
||||||
|
|
||||||
|
"DbrValues":{
|
||||||
|
}}
|
28
SourceGen/SGTestData/Expected/20280-label-placement_64tass.S
Normal file
28
SourceGen/SGTestData/Expected/20280-label-placement_64tass.S
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
.cpu "6502"
|
||||||
|
shortnm = $4000 ;short label
|
||||||
|
SomewhatLongName = $4001 ;somewhat longer label
|
||||||
|
|
||||||
|
* = $1000
|
||||||
|
lda shortnm
|
||||||
|
ldx SomewhatLongName
|
||||||
|
clc
|
||||||
|
bcc BranchTargetLongName
|
||||||
|
|
||||||
|
data
|
||||||
|
.byte $cc
|
||||||
|
|
||||||
|
ptr .var $00 ;local var with short name
|
||||||
|
PointerWithLongName .var $02 ;local var with longer name
|
||||||
|
BranchTargetLongName
|
||||||
|
sta ptr
|
||||||
|
stx PointerWithLongName
|
||||||
|
ldy data
|
||||||
|
lsr a
|
||||||
|
bcc shortb
|
||||||
|
shortb
|
||||||
|
nop
|
||||||
|
jmp done
|
||||||
|
|
||||||
|
done
|
||||||
|
rts
|
||||||
|
|
29
SourceGen/SGTestData/Expected/20280-label-placement_acme.S
Normal file
29
SourceGen/SGTestData/Expected/20280-label-placement_acme.S
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
!cpu 6502
|
||||||
|
shortnm = $4000 ;short label
|
||||||
|
SomewhatLongName = $4001 ;somewhat longer label
|
||||||
|
|
||||||
|
* = $1000
|
||||||
|
lda shortnm
|
||||||
|
ldx SomewhatLongName
|
||||||
|
clc
|
||||||
|
bcc BranchTargetLongName
|
||||||
|
|
||||||
|
data
|
||||||
|
!byte $cc
|
||||||
|
|
||||||
|
!zone Z00000a
|
||||||
|
.ptr = $00 ;local var with short name
|
||||||
|
.PointerWithLongName = $02 ;local var with longer name
|
||||||
|
BranchTargetLongName
|
||||||
|
sta .ptr
|
||||||
|
stx .PointerWithLongName
|
||||||
|
ldy data
|
||||||
|
lsr
|
||||||
|
bcc shortb
|
||||||
|
shortb
|
||||||
|
nop
|
||||||
|
jmp done
|
||||||
|
|
||||||
|
done
|
||||||
|
rts
|
||||||
|
|
28
SourceGen/SGTestData/Expected/20280-label-placement_cc65.S
Normal file
28
SourceGen/SGTestData/Expected/20280-label-placement_cc65.S
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
.setcpu "6502"
|
||||||
|
shortnm = $4000 ;short label
|
||||||
|
SomewhatLongName = $4001 ;somewhat longer label
|
||||||
|
|
||||||
|
.org $1000
|
||||||
|
lda shortnm
|
||||||
|
ldx SomewhatLongName
|
||||||
|
clc
|
||||||
|
bcc BranchTargetLongName
|
||||||
|
|
||||||
|
data:
|
||||||
|
.byte $cc
|
||||||
|
|
||||||
|
ptr .set $00 ;local var with short name
|
||||||
|
PointerWithLongName .set $02 ;local var with longer name
|
||||||
|
BranchTargetLongName:
|
||||||
|
sta ptr
|
||||||
|
stx PointerWithLongName
|
||||||
|
ldy data
|
||||||
|
lsr A
|
||||||
|
bcc shortb
|
||||||
|
shortb:
|
||||||
|
nop
|
||||||
|
jmp done
|
||||||
|
|
||||||
|
done:
|
||||||
|
rts
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
# 6502bench SourceGen generated linker script for 20280-label-placement
|
||||||
|
MEMORY {
|
||||||
|
MAIN: file=%O, start=%S, size=65536;
|
||||||
|
}
|
||||||
|
SEGMENTS {
|
||||||
|
CODE: load=MAIN, type=rw;
|
||||||
|
}
|
||||||
|
FEATURES {}
|
||||||
|
SYMBOLS {}
|
|
@ -0,0 +1,27 @@
|
||||||
|
shortnm equ $4000 ;short label
|
||||||
|
SomewhatLongName equ $4001 ;somewhat longer label
|
||||||
|
|
||||||
|
org $1000
|
||||||
|
lda shortnm
|
||||||
|
ldx SomewhatLongName
|
||||||
|
clc
|
||||||
|
bcc BranchTargetLongName
|
||||||
|
|
||||||
|
data
|
||||||
|
dfb $cc
|
||||||
|
|
||||||
|
]ptr equ $00 ;local var with short name
|
||||||
|
]PointerWithLongName equ $02 ;local var with longer name
|
||||||
|
BranchTargetLongName
|
||||||
|
sta ]ptr
|
||||||
|
stx ]PointerWithLongName
|
||||||
|
ldy data
|
||||||
|
lsr A
|
||||||
|
bcc shortb
|
||||||
|
shortb
|
||||||
|
nop
|
||||||
|
jmp done
|
||||||
|
|
||||||
|
done
|
||||||
|
rts
|
||||||
|
|
|
@ -34,17 +34,19 @@ be opened as the project file.
|
||||||
### Overriding Settings ###
|
### Overriding Settings ###
|
||||||
|
|
||||||
All tests are run with a fixed set of app settings, so that the tests look
|
All tests are run with a fixed set of app settings, so that the tests look
|
||||||
the same regardless of how the assemblers are configured. For example,
|
the same regardless of how the assemblers are configured in the app settings
|
||||||
upper-case conversion is disabled, and cycle counts are not shown.
|
file. For example, upper-case conversion is disabled, and cycle counts are
|
||||||
|
not shown.
|
||||||
|
|
||||||
Sometimes a test will want to exercise one of these settings, so we need
|
Sometimes a test will want to exercise one of these settings, so we need
|
||||||
a way to tell the test harness to override the default. We do this by
|
a way to tell the test harness to override the default. We do this by
|
||||||
creating project symbols.
|
creating project symbols:
|
||||||
|
|
||||||
| Name | Value | Description
|
| Name | Value | Description
|
||||||
| ---------------------- | ----- | -------------------------------------------|
|
| -------------------------- | ----- | -------------------------------------------|
|
||||||
| __ENABLE_LABEL_NEWLINE | any | Puts long labels on their own line |
|
| __ENABLE_LABEL_NEWLINE | any | Puts long labels on their own line |
|
||||||
| __ENABLE_CYCLE_COUNTS | any | Adds cycle count to end-of-line comments |
|
| __ENABLE_ALL_LABEL_NEWLINE | any | Puts all labels on their own line |
|
||||||
|
| __ENABLE_CYCLE_COUNTS | any | Adds cycle count to end-of-line comments |
|
||||||
|
|
||||||
### Execution ###
|
### Execution ###
|
||||||
|
|
||||||
|
@ -74,7 +76,7 @@ the "retain output" box in the test harness, the directory and its contents
|
||||||
will remain. This allows you to examine the outputs when investigating
|
will remain. This allows you to examine the outputs when investigating
|
||||||
failures.
|
failures.
|
||||||
|
|
||||||
As a safety measure, the directory will NOT be removed if it contains files
|
As a safety measure, a directory will NOT be removed if it contains files
|
||||||
that the test harness doesn't recognize.
|
that the test harness doesn't recognize.
|
||||||
|
|
||||||
### Updating Tests ###
|
### Updating Tests ###
|
||||||
|
@ -115,4 +117,3 @@ for a full explanation.
|
||||||
|
|
||||||
Some test projects and data files for exercising the visualization generators.
|
Some test projects and data files for exercising the visualization generators.
|
||||||
Not part of a formal test; load the projects and eyeball the results.
|
Not part of a formal test; load the projects and eyeball the results.
|
||||||
|
|
||||||
|
|
32
SourceGen/SGTestData/Source/20280-label-placement.S
Normal file
32
SourceGen/SGTestData/Source/20280-label-placement.S
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
; Copyright 2024 faddenSoft. All Rights Reserved.
|
||||||
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
|
;
|
||||||
|
; The symbol __ENABLE_ALL_LABEL_NEWLINE must be defined in the project
|
||||||
|
; symbols, so that labels are placed on their own lines whenever possible.
|
||||||
|
;
|
||||||
|
; Assembler: Merlin 32
|
||||||
|
|
||||||
|
org $1000
|
||||||
|
shortnm equ $4000
|
||||||
|
SomewhatLongName equ $4001
|
||||||
|
|
||||||
|
lda shortnm
|
||||||
|
ldx SomewhatLongName
|
||||||
|
clc
|
||||||
|
bcc BranchTargetLongName
|
||||||
|
data dfb $cc
|
||||||
|
|
||||||
|
]ptr equ $00
|
||||||
|
]PointerWithLongName equ $02
|
||||||
|
|
||||||
|
BranchTargetLongName
|
||||||
|
sta ]ptr
|
||||||
|
stx ]PointerWithLongName
|
||||||
|
ldy data
|
||||||
|
lsr A
|
||||||
|
bcc shortb
|
||||||
|
shortb nop
|
||||||
|
|
||||||
|
jmp done
|
||||||
|
|
||||||
|
done rts
|
|
@ -430,7 +430,8 @@ namespace SourceGen.Tests {
|
||||||
|
|
||||||
// Don't break lines with long labels. That way we can redefine "long"
|
// Don't break lines with long labels. That way we can redefine "long"
|
||||||
// without breaking our tests. (This is purely cosmetic.)
|
// without breaking our tests. (This is purely cosmetic.)
|
||||||
settings.SetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false);
|
settings.SetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
GenCommon.LabelPlacement.PreferSameLine);
|
||||||
|
|
||||||
// This could be on or off. Off seems less distracting.
|
// This could be on or off. Off seems less distracting.
|
||||||
settings.SetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS, false);
|
settings.SetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS, false);
|
||||||
|
@ -455,17 +456,23 @@ namespace SourceGen.Tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applies app setting overrides that were specified in the project settings.
|
/// Applies app setting overrides that were specified in the project properties.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void ApplyProjectSettings(AppSettings settings, DisasmProject project) {
|
private void ApplyProjectSettings(AppSettings settings, DisasmProject project) {
|
||||||
// We could probably make this a more general mechanism, but that would strain
|
// We could probably make this a more general mechanism, but that would strain
|
||||||
// things a bit, since we need to know the settings name, bool/int/string, and
|
// things a bit, since we need to know the settings name, bool/int/string, and
|
||||||
// desired value. Easier to just have a set of named features.
|
// desired value. Easier to just have a set of named features.
|
||||||
const string ENABLE_LABEL_NEWLINE = "__ENABLE_LABEL_NEWLINE";
|
const string ENABLE_LABEL_NEWLINE = "__ENABLE_LABEL_NEWLINE";
|
||||||
|
const string ENABLE_ALL_LABEL_NEWLINE = "__ENABLE_ALL_LABEL_NEWLINE";
|
||||||
const string ENABLE_CYCLE_COUNTS = "__ENABLE_CYCLE_COUNTS";
|
const string ENABLE_CYCLE_COUNTS = "__ENABLE_CYCLE_COUNTS";
|
||||||
|
|
||||||
if (project.ProjectProps.ProjectSyms.ContainsKey(ENABLE_LABEL_NEWLINE)) {
|
if (project.ProjectProps.ProjectSyms.ContainsKey(ENABLE_LABEL_NEWLINE)) {
|
||||||
settings.SetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, true);
|
settings.SetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
GenCommon.LabelPlacement.SplitIfTooLong);
|
||||||
|
}
|
||||||
|
if (project.ProjectProps.ProjectSyms.ContainsKey(ENABLE_ALL_LABEL_NEWLINE)) {
|
||||||
|
settings.SetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
GenCommon.LabelPlacement.PreferSeparateLine);
|
||||||
}
|
}
|
||||||
if (project.ProjectProps.ProjectSyms.ContainsKey(ENABLE_CYCLE_COUNTS)) {
|
if (project.ProjectProps.ProjectSyms.ContainsKey(ENABLE_CYCLE_COUNTS)) {
|
||||||
settings.SetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS, true);
|
settings.SetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS, true);
|
||||||
|
|
|
@ -75,8 +75,7 @@ namespace SourceGen.Tools.WpfGui {
|
||||||
|
|
||||||
public void Window_Loaded(object sender, RoutedEventArgs e) {
|
public void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||||
// Restore chart mode setting.
|
// Restore chart mode setting.
|
||||||
ChartMode mode = (ChartMode)AppSettings.Global.GetEnum(
|
ChartMode mode = AppSettings.Global.GetEnum(AppSettings.A2SC_MODE, ChartMode.HiRes1_L);
|
||||||
AppSettings.A2SC_MODE, typeof(ChartMode), (int)ChartMode.HiRes1_L);
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < ChartModeItems.Length; i++) {
|
for (int i = 0; i < ChartModeItems.Length; i++) {
|
||||||
if (ChartModeItems[i].Mode == mode) {
|
if (ChartModeItems[i].Mode == mode) {
|
||||||
|
@ -107,7 +106,7 @@ namespace SourceGen.Tools.WpfGui {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppSettings.Global.SetEnum(AppSettings.A2SC_MODE, typeof(ChartMode), (int)item.Mode);
|
AppSettings.Global.SetEnum(AppSettings.A2SC_MODE, item.Mode);
|
||||||
|
|
||||||
string text;
|
string text;
|
||||||
switch (item.Mode) {
|
switch (item.Mode) {
|
||||||
|
|
|
@ -55,8 +55,7 @@ namespace SourceGen.Tools.WpfGui {
|
||||||
|
|
||||||
public void Window_Loaded(object sender, RoutedEventArgs e) {
|
public void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||||
// Restore chart mode setting.
|
// Restore chart mode setting.
|
||||||
ChartMode mode = (ChartMode)AppSettings.Global.GetEnum(
|
ChartMode mode = AppSettings.Global.GetEnum(AppSettings.ASCCH_MODE, ChartMode.Standard);
|
||||||
AppSettings.ASCCH_MODE, typeof(ChartMode), (int)ChartMode.Standard);
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < ChartModeItems.Length; i++) {
|
for (int i = 0; i < ChartModeItems.Length; i++) {
|
||||||
if (ChartModeItems[i].Mode == mode) {
|
if (ChartModeItems[i].Mode == mode) {
|
||||||
|
@ -87,7 +86,7 @@ namespace SourceGen.Tools.WpfGui {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppSettings.Global.SetEnum(AppSettings.ASCCH_MODE, typeof(ChartMode), (int)item.Mode);
|
AppSettings.Global.SetEnum(AppSettings.ASCCH_MODE, item.Mode);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Draw box contents.
|
// Draw box contents.
|
||||||
|
|
|
@ -111,8 +111,8 @@ namespace SourceGen.Tools.WpfGui {
|
||||||
AsciiOnlyDump = AppSettings.Global.GetBool(AppSettings.HEXD_ASCII_ONLY, false);
|
AsciiOnlyDump = AppSettings.Global.GetBool(AppSettings.HEXD_ASCII_ONLY, false);
|
||||||
|
|
||||||
// Restore conv mode setting.
|
// Restore conv mode setting.
|
||||||
CharConvMode mode = (CharConvMode)AppSettings.Global.GetEnum(
|
CharConvMode mode =
|
||||||
AppSettings.HEXD_CHAR_CONV, typeof(CharConvMode), (int)CharConvMode.Ascii);
|
AppSettings.Global.GetEnum(AppSettings.HEXD_CHAR_CONV, CharConvMode.Ascii);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < CharConvItems.Length; i++) {
|
for (int i = 0; i < CharConvItems.Length; i++) {
|
||||||
if (CharConvItems[i].Mode == mode) {
|
if (CharConvItems[i].Mode == mode) {
|
||||||
|
@ -156,8 +156,7 @@ namespace SourceGen.Tools.WpfGui {
|
||||||
|
|
||||||
// Keep app settings up to date.
|
// Keep app settings up to date.
|
||||||
AppSettings.Global.SetBool(AppSettings.HEXD_ASCII_ONLY, mAsciiOnlyDump);
|
AppSettings.Global.SetBool(AppSettings.HEXD_ASCII_ONLY, mAsciiOnlyDump);
|
||||||
AppSettings.Global.SetEnum(AppSettings.HEXD_CHAR_CONV, typeof(CharConvMode),
|
AppSettings.Global.SetEnum(AppSettings.HEXD_CHAR_CONV, item.Mode);
|
||||||
(int)item.Mode);
|
|
||||||
|
|
||||||
mFormatter = new Formatter(config);
|
mFormatter = new Formatter(config);
|
||||||
HexDumpLines.Reformat(mFormatter);
|
HexDumpLines.Reformat(mFormatter);
|
||||||
|
|
|
@ -112,8 +112,8 @@ namespace SourceGen.Tools.WpfGui {
|
||||||
|
|
||||||
public void Window_Loaded(object sender, RoutedEventArgs e) {
|
public void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||||
// Restore chart settings.
|
// Restore chart settings.
|
||||||
CpuDef.CpuType type = (CpuDef.CpuType)AppSettings.Global.GetEnum(
|
CpuDef.CpuType type =
|
||||||
AppSettings.INSTCH_MODE, typeof(CpuDef.CpuType), (int)CpuDef.CpuType.Cpu6502);
|
AppSettings.Global.GetEnum(AppSettings.INSTCH_MODE, CpuDef.CpuType.Cpu6502);
|
||||||
ShowUndocumented = AppSettings.Global.GetBool(AppSettings.INSTCH_SHOW_UNDOC, true);
|
ShowUndocumented = AppSettings.Global.GetBool(AppSettings.INSTCH_SHOW_UNDOC, true);
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
@ -146,8 +146,7 @@ namespace SourceGen.Tools.WpfGui {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push current choice to settings.
|
// Push current choice to settings.
|
||||||
AppSettings.Global.SetEnum(AppSettings.INSTCH_MODE, typeof(CpuDef.CpuType),
|
AppSettings.Global.SetEnum(AppSettings.INSTCH_MODE, item.Type);
|
||||||
(int)item.Type);
|
|
||||||
AppSettings.Global.SetBool(AppSettings.INSTCH_SHOW_UNDOC, mShowUndocumented);
|
AppSettings.Global.SetBool(AppSettings.INSTCH_SHOW_UNDOC, mShowUndocumented);
|
||||||
|
|
||||||
// Populate the items source.
|
// Populate the items source.
|
||||||
|
|
|
@ -820,10 +820,20 @@ limitations under the License.
|
||||||
<TextBlock Text="General code generation:" Margin="4,16,0,0"/>
|
<TextBlock Text="General code generation:" Margin="4,16,0,0"/>
|
||||||
<CheckBox Content="Show cycle counts in comments" Margin="4,8,0,0"
|
<CheckBox Content="Show cycle counts in comments" Margin="4,8,0,0"
|
||||||
IsChecked="{Binding ShowCycleCountsAsm}"/>
|
IsChecked="{Binding ShowCycleCountsAsm}"/>
|
||||||
<CheckBox Content="Put long labels on separate line" Margin="4,8,0,0"
|
<CheckBox Content="Identify assembler in output" Margin="4,6,0,0"
|
||||||
IsChecked="{Binding LongLabelNewLine}"/>
|
|
||||||
<CheckBox Content="Identify assembler in output" Margin="4,8,0,0"
|
|
||||||
IsChecked="{Binding AddIdentComment}"/>
|
IsChecked="{Binding AddIdentComment}"/>
|
||||||
|
<StackPanel Orientation="Vertical" Margin="10,6,0,0">
|
||||||
|
<TextBlock Text="Put labels on their own line..."/>
|
||||||
|
<RadioButton GroupName="labelLineGroup" Margin="0,4,0,0"
|
||||||
|
Content="Only when required"
|
||||||
|
IsChecked="{Binding LabelPlacement_PreferSameLine}"/>
|
||||||
|
<RadioButton GroupName="labelLineGroup" Margin="0,4,0,0"
|
||||||
|
Content="When the label is wider than the field"
|
||||||
|
IsChecked="{Binding LabelPlacement_SplitIfTooLong}"/>
|
||||||
|
<RadioButton GroupName="labelLineGroup" Margin="0,4,0,0"
|
||||||
|
Content="Whenever possible"
|
||||||
|
IsChecked="{Binding LabelPlacement_PreferSeparateLine}"/>
|
||||||
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ using CommonUtil;
|
||||||
using AssemblerInfo = SourceGen.AsmGen.AssemblerInfo;
|
using AssemblerInfo = SourceGen.AsmGen.AssemblerInfo;
|
||||||
using AssemblerConfig = SourceGen.AsmGen.AssemblerConfig;
|
using AssemblerConfig = SourceGen.AsmGen.AssemblerConfig;
|
||||||
using ExpressionMode = Asm65.Formatter.FormatConfig.ExpressionMode;
|
using ExpressionMode = Asm65.Formatter.FormatConfig.ExpressionMode;
|
||||||
|
using LabelPlacement = SourceGen.AsmGen.GenCommon.LabelPlacement;
|
||||||
|
|
||||||
namespace SourceGen.WpfGui {
|
namespace SourceGen.WpfGui {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -280,8 +281,8 @@ namespace SourceGen.WpfGui {
|
||||||
UpperOperandXY = mSettings.GetBool(AppSettings.FMT_UPPER_OPERAND_XY, false);
|
UpperOperandXY = mSettings.GetBool(AppSettings.FMT_UPPER_OPERAND_XY, false);
|
||||||
|
|
||||||
Debug.Assert(clipboardFormatComboBox.Items.Count == sClipboardFormatItems.Length);
|
Debug.Assert(clipboardFormatComboBox.Items.Count == sClipboardFormatItems.Length);
|
||||||
int clipIndex = mSettings.GetEnum(AppSettings.CLIP_LINE_FORMAT,
|
int clipIndex = (int)mSettings.GetEnum(AppSettings.CLIP_LINE_FORMAT,
|
||||||
typeof(MainController.ClipLineFormat), 0);
|
MainController.ClipLineFormat.AssemblerSource);
|
||||||
if (clipIndex >= 0 && clipIndex < sClipboardFormatItems.Length) {
|
if (clipIndex >= 0 && clipIndex < sClipboardFormatItems.Length) {
|
||||||
// require Value == clipIndex because we're lazy and don't want to search
|
// require Value == clipIndex because we're lazy and don't want to search
|
||||||
Debug.Assert((int)sClipboardFormatItems[clipIndex].Value == clipIndex);
|
Debug.Assert((int)sClipboardFormatItems[clipIndex].Value == clipIndex);
|
||||||
|
@ -414,8 +415,7 @@ namespace SourceGen.WpfGui {
|
||||||
private void ClipboardFormatComboBox_SelectionChanged(object sender,
|
private void ClipboardFormatComboBox_SelectionChanged(object sender,
|
||||||
SelectionChangedEventArgs e) {
|
SelectionChangedEventArgs e) {
|
||||||
ClipboardFormatItem item = (ClipboardFormatItem)clipboardFormatComboBox.SelectedItem;
|
ClipboardFormatItem item = (ClipboardFormatItem)clipboardFormatComboBox.SelectedItem;
|
||||||
mSettings.SetEnum(AppSettings.CLIP_LINE_FORMAT, typeof(MainController.ClipLineFormat),
|
mSettings.SetEnum(AppSettings.CLIP_LINE_FORMAT, item.Value);
|
||||||
(int)item.Value);
|
|
||||||
IsDirty = true;
|
IsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,14 +757,6 @@ namespace SourceGen.WpfGui {
|
||||||
IsDirty = true;
|
IsDirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public bool LongLabelNewLine {
|
|
||||||
get { return mSettings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false); }
|
|
||||||
set {
|
|
||||||
mSettings.SetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, value);
|
|
||||||
OnPropertyChanged();
|
|
||||||
IsDirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public bool AddIdentComment {
|
public bool AddIdentComment {
|
||||||
get { return mSettings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false); }
|
get { return mSettings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false); }
|
||||||
set {
|
set {
|
||||||
|
@ -774,6 +766,58 @@ namespace SourceGen.WpfGui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// label placement radio buttons
|
||||||
|
public bool LabelPlacement_PreferSameLine {
|
||||||
|
get {
|
||||||
|
LabelPlacement place = mSettings.GetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
LabelPlacement.SplitIfTooLong);
|
||||||
|
return place == LabelPlacement.PreferSameLine;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if (value) {
|
||||||
|
mSettings.SetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
LabelPlacement.PreferSameLine);
|
||||||
|
LabelPlacementChanged();
|
||||||
|
IsDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool LabelPlacement_SplitIfTooLong {
|
||||||
|
get {
|
||||||
|
LabelPlacement place = mSettings.GetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
LabelPlacement.SplitIfTooLong);
|
||||||
|
return place == LabelPlacement.SplitIfTooLong;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if (value) {
|
||||||
|
mSettings.SetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
LabelPlacement.SplitIfTooLong);
|
||||||
|
LabelPlacementChanged();
|
||||||
|
IsDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool LabelPlacement_PreferSeparateLine {
|
||||||
|
get {
|
||||||
|
LabelPlacement place = mSettings.GetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
LabelPlacement.SplitIfTooLong);
|
||||||
|
return place == LabelPlacement.PreferSeparateLine;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if (value) {
|
||||||
|
mSettings.SetEnum(AppSettings.SRCGEN_LABEL_NEW_LINE,
|
||||||
|
LabelPlacement.PreferSeparateLine);
|
||||||
|
LabelPlacementChanged();
|
||||||
|
IsDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void LabelPlacementChanged() {
|
||||||
|
OnPropertyChanged(nameof(LabelPlacement_PreferSameLine));
|
||||||
|
OnPropertyChanged(nameof(LabelPlacement_SplitIfTooLong));
|
||||||
|
OnPropertyChanged(nameof(LabelPlacement_PreferSeparateLine));
|
||||||
|
}
|
||||||
|
|
||||||
private void Loaded_AsmConfig() {
|
private void Loaded_AsmConfig() {
|
||||||
asmConfigComboBox.SelectedItem = AssemblerInfo.GetAssemblerInfo(mInitialAsmId);
|
asmConfigComboBox.SelectedItem = AssemblerInfo.GetAssemblerInfo(mInitialAsmId);
|
||||||
if (asmConfigComboBox.SelectedIndex < 0) {
|
if (asmConfigComboBox.SelectedIndex < 0) {
|
||||||
|
|
|
@ -293,8 +293,7 @@ namespace SourceGen.WpfGui {
|
||||||
AnalyzeStringRanges(item.Mode);
|
AnalyzeStringRanges(item.Mode);
|
||||||
UpdateControls();
|
UpdateControls();
|
||||||
|
|
||||||
AppSettings.Global.SetEnum(AppSettings.OPED_DEFAULT_STRING_ENCODING,
|
AppSettings.Global.SetEnum(AppSettings.OPED_DEFAULT_STRING_ENCODING, item.Mode);
|
||||||
typeof(TextScanMode), (int)item.Mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
||||||
|
@ -780,9 +779,8 @@ namespace SourceGen.WpfGui {
|
||||||
|
|
||||||
// Get the previous mode selected in the combo box. If the format descriptor
|
// Get the previous mode selected in the combo box. If the format descriptor
|
||||||
// doesn't specify a string, we'll use this.
|
// doesn't specify a string, we'll use this.
|
||||||
TextScanMode textMode = (TextScanMode)AppSettings.Global.GetEnum(
|
TextScanMode textMode = AppSettings.Global.GetEnum(
|
||||||
AppSettings.OPED_DEFAULT_STRING_ENCODING, typeof(TextScanMode),
|
AppSettings.OPED_DEFAULT_STRING_ENCODING, TextScanMode.LowHighAscii);
|
||||||
(int)TextScanMode.LowHighAscii);
|
|
||||||
|
|
||||||
if (dfd == null) {
|
if (dfd == null) {
|
||||||
radioDefaultFormat.IsChecked = true;
|
radioDefaultFormat.IsChecked = true;
|
||||||
|
|
|
@ -235,8 +235,8 @@ namespace SourceGen.WpfGui {
|
||||||
AsmCommentColWidth = colWidths[3];
|
AsmCommentColWidth = colWidths[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
TextMode mode = (TextMode)AppSettings.Global.GetEnum(AppSettings.EXPORT_TEXT_MODE,
|
TextMode mode = AppSettings.Global.GetEnum(AppSettings.EXPORT_TEXT_MODE,
|
||||||
typeof(TextMode), (int)TextMode.PlainText);
|
TextMode.PlainText);
|
||||||
if (mode == TextMode.PlainText) {
|
if (mode == TextMode.PlainText) {
|
||||||
TextModePlain = true;
|
TextModePlain = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -273,7 +273,7 @@ namespace SourceGen.WpfGui {
|
||||||
} else {
|
} else {
|
||||||
mode = TextMode.Csv;
|
mode = TextMode.Csv;
|
||||||
}
|
}
|
||||||
AppSettings.Global.SetEnum(AppSettings.EXPORT_TEXT_MODE, typeof(TextMode), (int)mode);
|
AppSettings.Global.SetEnum(AppSettings.EXPORT_TEXT_MODE, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -55,17 +55,15 @@ namespace SourceGen.WpfGui {
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
DataContext = this;
|
DataContext = this;
|
||||||
|
|
||||||
Format =
|
Format = AppSettings.Global.GetEnum(AppSettings.LABGEN_FORMAT,
|
||||||
(LabelFileGenerator.LabelFmt)AppSettings.Global.GetEnum(AppSettings.LABGEN_FORMAT,
|
LabelFileGenerator.LabelFmt.VICE);
|
||||||
typeof(LabelFileGenerator.LabelFmt), (int)LabelFileGenerator.LabelFmt.VICE);
|
|
||||||
UpdateFormats();
|
UpdateFormats();
|
||||||
mIncludeAutoLabels = AppSettings.Global.GetBool(AppSettings.LABGEN_INCLUDE_AUTO, false);
|
mIncludeAutoLabels = AppSettings.Global.GetBool(AppSettings.LABGEN_INCLUDE_AUTO, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
||||||
// Save settings.
|
// Save settings.
|
||||||
AppSettings.Global.SetEnum(AppSettings.LABGEN_FORMAT,
|
AppSettings.Global.SetEnum(AppSettings.LABGEN_FORMAT, Format);
|
||||||
typeof(LabelFileGenerator.LabelFmt), (int)Format);
|
|
||||||
AppSettings.Global.SetBool(AppSettings.LABGEN_INCLUDE_AUTO, mIncludeAutoLabels);
|
AppSettings.Global.SetBool(AppSettings.LABGEN_INCLUDE_AUTO, mIncludeAutoLabels);
|
||||||
DialogResult = true;
|
DialogResult = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user