mirror of https://github.com/fadden/6502bench.git
Compare commits
2 Commits
da91d9fc0e
...
4322a0c231
Author | SHA1 | Date |
---|---|---|
Andy McFadden | 4322a0c231 | |
Andy McFadden | e425237783 |
|
@ -42,10 +42,10 @@ namespace CommonUtil {
|
|||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Usage:
|
||||
/// AppDomain.CurrentDomain.UnhandledException +=
|
||||
/// new UnhandledExceptionEventHandler(CommonUtil.Misc.CrashReporter);
|
||||
/// <code>AppDomain.CurrentDomain.UnhandledException +=
|
||||
/// new UnhandledExceptionEventHandler(CommonUtil.Misc.CrashReporter);</code>
|
||||
///
|
||||
/// Thanks: https://stackoverflow.com/a/21308327/294248
|
||||
/// Thanks: <see href="https://stackoverflow.com/a/21308327/294248"/>.
|
||||
/// </remarks>
|
||||
public static void CrashReporter(object sender, UnhandledExceptionEventArgs e) {
|
||||
const string CRASH_PATH = @"CrashLog.txt";
|
||||
|
@ -80,7 +80,7 @@ namespace CommonUtil {
|
|||
/// faster than setting array elements individually.
|
||||
/// </summary>
|
||||
/// <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
|
||||
/// Buffer.BlockCopy or unsafe code. Apparently .NET Core has an Array.Fill(), but
|
||||
|
|
|
@ -124,9 +124,13 @@ namespace SourceGen {
|
|||
// Source generation settings.
|
||||
public const string SRCGEN_DEFAULT_ASM = "srcgen-default-asm";
|
||||
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";
|
||||
|
||||
// Label file generation settings.
|
||||
public const string LABGEN_FORMAT = "labgen-format";
|
||||
public const string LABGEN_INCLUDE_AUTO = "labgen-include-auto";
|
||||
|
||||
// Assembler settings prefix
|
||||
public const string ASM_CONFIG_PREFIX = "asm-config-";
|
||||
|
||||
|
@ -287,21 +291,20 @@ namespace SourceGen {
|
|||
/// <summary>
|
||||
/// Retrieves an enumerated value setting.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Enumerated type.</typeparam>
|
||||
/// <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>
|
||||
/// <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
|
||||
/// type.</returns>
|
||||
public int GetEnum(string name, Type enumType, int defaultValue) {
|
||||
/// name exists, or the stored value is not a member of the enumeration.</returns>
|
||||
public T GetEnum<T>(string name, T defaultValue) {
|
||||
if (!mSettings.TryGetValue(name, out string valueStr)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
object o = Enum.Parse(enumType, valueStr);
|
||||
return (int)o;
|
||||
object o = Enum.Parse(typeof(T), valueStr);
|
||||
return (T)o;
|
||||
} catch (ArgumentException ae) {
|
||||
Debug.WriteLine("Failed to parse " + valueStr + " (enum " + enumType + "): " +
|
||||
Debug.WriteLine("Failed to parse '" + valueStr + "' (enum " + typeof(T) + "): " +
|
||||
ae.Message);
|
||||
return defaultValue;
|
||||
}
|
||||
|
@ -310,14 +313,20 @@ namespace SourceGen {
|
|||
/// <summary>
|
||||
/// Sets an enumerated setting.
|
||||
/// </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="enumType">Enum type.</param>
|
||||
/// <param name="value">Setting value (integer enum index).</param>
|
||||
public void SetEnum(string name, Type enumType, int value) {
|
||||
string newVal = Enum.GetName(enumType, value);
|
||||
public void SetEnum<T>(string name, T 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) {
|
||||
// Shouldn't be possible if an enum value of the correct type is passed in.
|
||||
Debug.WriteLine("Unable to get enum name type=" + enumType + " value=" + value);
|
||||
Debug.WriteLine("Unable to get enum name type=" + typeof(T) + " value=" + value);
|
||||
return;
|
||||
}
|
||||
if (!mSettings.TryGetValue(name, out string oldValue) || oldValue != newVal) {
|
||||
|
|
|
@ -62,9 +62,9 @@ namespace SourceGen.AsmGen {
|
|||
private string mWorkDirectory;
|
||||
|
||||
/// <summary>
|
||||
/// If set, long labels get their own line.
|
||||
/// Influences whether labels are put on their own line.
|
||||
/// </summary>
|
||||
private bool mLongLabelNewLine;
|
||||
private GenCommon.LabelPlacement mLabelNewLine;
|
||||
|
||||
/// <summary>
|
||||
/// Output column widths.
|
||||
|
@ -198,7 +198,8 @@ namespace SourceGen.AsmGen {
|
|||
mFileNameBase = fileNameBase;
|
||||
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,
|
||||
AssemblerInfo.Id.Acme);
|
||||
|
@ -667,7 +668,9 @@ namespace SourceGen.AsmGen {
|
|||
!string.Equals(opcode, sDataOpNames.EquDirective,
|
||||
StringComparison.InvariantCultureIgnoreCase)) {
|
||||
|
||||
if (mLongLabelNewLine && label.Length >= mColumnWidths[0]) {
|
||||
if (mLabelNewLine == GenCommon.LabelPlacement.PreferSeparateLine ||
|
||||
(mLabelNewLine == GenCommon.LabelPlacement.SplitIfTooLong &&
|
||||
label.Length >= mColumnWidths[0])) {
|
||||
mOutStream.WriteLine(label);
|
||||
label = string.Empty;
|
||||
}
|
||||
|
|
|
@ -57,9 +57,9 @@ namespace SourceGen.AsmGen {
|
|||
private string mWorkDirectory;
|
||||
|
||||
/// <summary>
|
||||
/// If set, long labels get their own line.
|
||||
/// Influences whether labels are put on their own line.
|
||||
/// </summary>
|
||||
private bool mLongLabelNewLine;
|
||||
private GenCommon.LabelPlacement mLabelNewLine;
|
||||
|
||||
/// <summary>
|
||||
/// Output column widths.
|
||||
|
@ -188,7 +188,8 @@ namespace SourceGen.AsmGen {
|
|||
mFileNameBase = fileNameBase;
|
||||
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,
|
||||
AssemblerInfo.Id.Cc65);
|
||||
|
@ -659,7 +660,9 @@ namespace SourceGen.AsmGen {
|
|||
StringComparison.InvariantCultureIgnoreCase)) {
|
||||
label += ':';
|
||||
|
||||
if (mLongLabelNewLine && label.Length >= mColumnWidths[0]) {
|
||||
if (mLabelNewLine == GenCommon.LabelPlacement.PreferSeparateLine ||
|
||||
(mLabelNewLine == GenCommon.LabelPlacement.SplitIfTooLong &&
|
||||
label.Length >= mColumnWidths[0])) {
|
||||
mOutStream.WriteLine(label);
|
||||
label = string.Empty;
|
||||
}
|
||||
|
|
|
@ -57,9 +57,9 @@ namespace SourceGen.AsmGen {
|
|||
private string mWorkDirectory;
|
||||
|
||||
/// <summary>
|
||||
/// If set, long labels get their own line.
|
||||
/// Influences whether labels are put on their own line.
|
||||
/// </summary>
|
||||
private bool mLongLabelNewLine;
|
||||
private GenCommon.LabelPlacement mLabelNewLine;
|
||||
|
||||
/// <summary>
|
||||
/// Output column widths.
|
||||
|
@ -174,7 +174,8 @@ namespace SourceGen.AsmGen {
|
|||
mFileNameBase = fileNameBase;
|
||||
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,
|
||||
AssemblerInfo.Id.Merlin32);
|
||||
|
@ -606,11 +607,14 @@ namespace SourceGen.AsmGen {
|
|||
// IGenerator
|
||||
public void OutputLine(string label, string opcode, string operand, string comment) {
|
||||
// Split long label, but not on EQU directives (confuses the assembler).
|
||||
if (mLongLabelNewLine && label.Length >= mColumnWidths[0] &&
|
||||
!string.Equals(opcode, sDataOpNames.EquDirective,
|
||||
if (!string.IsNullOrEmpty(label) && !string.Equals(opcode, sDataOpNames.EquDirective,
|
||||
StringComparison.InvariantCultureIgnoreCase)) {
|
||||
mOutStream.WriteLine(label);
|
||||
label = string.Empty;
|
||||
if (mLabelNewLine == GenCommon.LabelPlacement.PreferSeparateLine ||
|
||||
(mLabelNewLine == GenCommon.LabelPlacement.SplitIfTooLong &&
|
||||
label.Length >= mColumnWidths[0])) {
|
||||
mOutStream.WriteLine(label);
|
||||
label = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
mLineBuilder.Clear();
|
||||
|
|
|
@ -73,9 +73,9 @@ namespace SourceGen.AsmGen {
|
|||
private string mWorkDirectory;
|
||||
|
||||
/// <summary>
|
||||
/// If set, long labels get their own line.
|
||||
/// Influences whether labels are put on their own line.
|
||||
/// </summary>
|
||||
private bool mLongLabelNewLine;
|
||||
private GenCommon.LabelPlacement mLabelNewLine;
|
||||
|
||||
/// <summary>
|
||||
/// Output column widths.
|
||||
|
@ -201,7 +201,8 @@ namespace SourceGen.AsmGen {
|
|||
mFileNameBase = fileNameBase;
|
||||
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,
|
||||
AssemblerInfo.Id.Tass64);
|
||||
|
@ -777,7 +778,9 @@ namespace SourceGen.AsmGen {
|
|||
!string.Equals(opcode, sDataOpNames.VarDirective,
|
||||
StringComparison.InvariantCultureIgnoreCase)) {
|
||||
|
||||
if (mLongLabelNewLine && label.Length >= mColumnWidths[0]) {
|
||||
if (mLabelNewLine == GenCommon.LabelPlacement.PreferSeparateLine ||
|
||||
(mLabelNewLine == GenCommon.LabelPlacement.SplitIfTooLong &&
|
||||
label.Length >= mColumnWidths[0])) {
|
||||
mOutStream.WriteLine(label);
|
||||
label = string.Empty;
|
||||
}
|
||||
|
|
|
@ -23,11 +23,19 @@ using Asm65;
|
|||
using CommonUtil;
|
||||
|
||||
namespace SourceGen.AsmGen {
|
||||
/// <summary>
|
||||
/// Code common to all assembly source generators.
|
||||
/// </summary>
|
||||
public class GenCommon {
|
||||
public enum LabelPlacement {
|
||||
Unknown = 0,
|
||||
PreferSameLine,
|
||||
SplitIfTooLong,
|
||||
PreferSeparateLine,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates assembly source.
|
||||
///
|
||||
/// This code is common to all generators.
|
||||
/// </summary>
|
||||
/// <param name="gen">Reference to generator object (presumably the caller).</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.
|
||||
tmplStr = tmplStr.Replace("$ProjectName$", mProject.DataFileName);
|
||||
tmplStr = tmplStr.Replace("$AppVersion$", App.ProgramVersion.ToString());
|
||||
string expModeStr = ((Formatter.FormatConfig.ExpressionMode)
|
||||
AppSettings.Global.GetEnum(AppSettings.FMT_EXPRESSION_MODE,
|
||||
typeof(Formatter.FormatConfig.ExpressionMode),
|
||||
(int)Formatter.FormatConfig.ExpressionMode.Unknown)).ToString();
|
||||
string expModeStr = AppSettings.Global.GetEnum(AppSettings.FMT_EXPRESSION_MODE,
|
||||
Formatter.FormatConfig.ExpressionMode.Unknown).ToString();
|
||||
tmplStr = tmplStr.Replace("$ExpressionStyle$", expModeStr);
|
||||
string dateStr = DateTime.Now.ToString("yyyy/MM/dd");
|
||||
string timeStr = DateTime.Now.ToString("HH:mm:ss zzz");
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright 2019 faddenSoft
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace SourceGen {
|
||||
/// <summary>
|
||||
/// Label file generator.
|
||||
/// </summary>
|
||||
public class LabelFileGenerator {
|
||||
public enum LabelFmt {
|
||||
Unknown = 0,
|
||||
VICE,
|
||||
}
|
||||
|
||||
private DisasmProject mProject;
|
||||
private LabelFmt mFormat;
|
||||
private bool mIncludeAutoLabels;
|
||||
|
||||
public LabelFileGenerator(DisasmProject project, LabelFmt format, bool includeAutoLabels) {
|
||||
mProject = project;
|
||||
mFormat = format;
|
||||
mIncludeAutoLabels = includeAutoLabels;
|
||||
}
|
||||
|
||||
public void Generate(StreamWriter outStream) {
|
||||
List<Symbol> symList = new List<Symbol>();
|
||||
|
||||
foreach (Symbol sym in mProject.SymbolTable) {
|
||||
bool include;
|
||||
switch (sym.SymbolSource) {
|
||||
case Symbol.Source.User:
|
||||
case Symbol.Source.AddrPreLabel:
|
||||
include = true;
|
||||
break;
|
||||
case Symbol.Source.Auto:
|
||||
include = mIncludeAutoLabels;
|
||||
break;
|
||||
case Symbol.Source.Project:
|
||||
case Symbol.Source.Platform:
|
||||
case Symbol.Source.Variable:
|
||||
default:
|
||||
include = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (include) {
|
||||
symList.Add(sym);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort alphabetically. Not necessary, but it could make a "diff" easier to read.
|
||||
symList.Sort((a, b) => Symbol.Compare(Symbol.SymbolSortField.Name, true, a, b));
|
||||
|
||||
// VICE format is "add_label <address> <label>", but may be abbreviated "al".
|
||||
// We could also use ACME format ("labelname = $1234 ; Maybe a comment").
|
||||
foreach (Symbol sym in symList) {
|
||||
outStream.WriteLine("al " + sym.Value.ToString("x6") + " " + sym.Label);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -345,7 +345,8 @@ namespace SourceGen {
|
|||
settings.SetString(AppSettings.FMT_OPERAND_PREFIX_LONG, "f:");
|
||||
|
||||
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
|
||||
settings.SetBool(AppSettings.DEBUG_MENU_ENABLED, true);
|
||||
|
@ -1462,10 +1463,8 @@ namespace SourceGen {
|
|||
return;
|
||||
}
|
||||
|
||||
ClipLineFormat format = (ClipLineFormat)AppSettings.Global.GetEnum(
|
||||
AppSettings.CLIP_LINE_FORMAT,
|
||||
typeof(ClipLineFormat),
|
||||
(int)ClipLineFormat.AssemblerSource);
|
||||
ClipLineFormat format = AppSettings.Global.GetEnum(AppSettings.CLIP_LINE_FORMAT,
|
||||
ClipLineFormat.AssemblerSource);
|
||||
|
||||
int[] rightWidths = new int[] { 16, 6, 16, 80 };
|
||||
|
||||
|
@ -2557,6 +2556,47 @@ namespace SourceGen {
|
|||
}
|
||||
}
|
||||
|
||||
public void GenerateLabels() {
|
||||
GenerateLabels dlg = new GenerateLabels(mMainWin);
|
||||
if (dlg.ShowDialog() == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
string ext;
|
||||
string filter;
|
||||
switch (dlg.Format) {
|
||||
case LabelFileGenerator.LabelFmt.VICE:
|
||||
ext = ".vs";
|
||||
filter = "VICE commands (*.vs)|*.vs";
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "bad format");
|
||||
return;
|
||||
}
|
||||
|
||||
SaveFileDialog fileDlg = new SaveFileDialog() {
|
||||
Filter = filter,
|
||||
FilterIndex = 1,
|
||||
ValidateNames = true,
|
||||
AddExtension = true, // doesn't add extension if non-ext file exists
|
||||
FileName = "labels" + ext
|
||||
};
|
||||
if (fileDlg.ShowDialog() != true) {
|
||||
return;
|
||||
}
|
||||
string pathName = Path.GetFullPath(fileDlg.FileName);
|
||||
try {
|
||||
using (StreamWriter writer = new StreamWriter(pathName, false)) {
|
||||
LabelFileGenerator gen = new LabelFileGenerator(mProject,
|
||||
dlg.Format, dlg.IncludeAutoLabels);
|
||||
gen.Generate(writer);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
MessageBox.Show("Error: " + ex.Message, "Failed", MessageBoxButton.OK,
|
||||
MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
public void Find() {
|
||||
FindBox dlg = new FindBox(mMainWin, mFindString);
|
||||
if (dlg.ShowDialog() == true) {
|
||||
|
|
Binary file not shown.
|
@ -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":{
|
||||
}}
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ###
|
||||
|
||||
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,
|
||||
upper-case conversion is disabled, and cycle counts are not shown.
|
||||
the same regardless of how the assemblers are configured in the app settings
|
||||
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
|
||||
a way to tell the test harness to override the default. We do this by
|
||||
creating project symbols.
|
||||
creating project symbols:
|
||||
|
||||
| Name | Value | Description
|
||||
| ---------------------- | ----- | -------------------------------------------|
|
||||
| __ENABLE_LABEL_NEWLINE | any | Puts long labels on their own line |
|
||||
| __ENABLE_CYCLE_COUNTS | any | Adds cycle count to end-of-line comments |
|
||||
| Name | Value | Description
|
||||
| -------------------------- | ----- | -------------------------------------------|
|
||||
| __ENABLE_LABEL_NEWLINE | any | Puts long labels on their own line |
|
||||
| __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 ###
|
||||
|
||||
|
@ -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
|
||||
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.
|
||||
|
||||
### Updating Tests ###
|
||||
|
@ -115,4 +117,3 @@ for a full explanation.
|
|||
|
||||
Some test projects and data files for exercising the visualization generators.
|
||||
Not part of a formal test; load the projects and eyeball the results.
|
||||
|
||||
|
|
|
@ -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
|
|
@ -79,6 +79,7 @@
|
|||
<Compile Include="DailyTips.cs" />
|
||||
<Compile Include="Exporter.cs" />
|
||||
<Compile Include="FormattedOperandCache.cs" />
|
||||
<Compile Include="LabelFileGenerator.cs" />
|
||||
<Compile Include="LocalVariableLookup.cs" />
|
||||
<Compile Include="MessageList.cs" />
|
||||
<Compile Include="Sgec.cs" />
|
||||
|
@ -188,6 +189,9 @@
|
|||
<Compile Include="WpfGui\FormatAddressTable.xaml.cs">
|
||||
<DependentUpon>FormatAddressTable.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WpfGui\GenerateLabels.xaml.cs">
|
||||
<DependentUpon>GenerateLabels.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WpfGui\GotoBox.xaml.cs">
|
||||
<DependentUpon>GotoBox.xaml</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -413,6 +417,10 @@
|
|||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="WpfGui\GenerateLabels.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="WpfGui\GotoBox.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -495,4 +503,4 @@
|
|||
<Resource Include="Res\RedX.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -430,7 +430,8 @@ namespace SourceGen.Tests {
|
|||
|
||||
// Don't break lines with long labels. That way we can redefine "long"
|
||||
// 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.
|
||||
settings.SetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS, false);
|
||||
|
@ -455,17 +456,23 @@ namespace SourceGen.Tests {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies app setting overrides that were specified in the project settings.
|
||||
/// Applies app setting overrides that were specified in the project properties.
|
||||
/// </summary>
|
||||
private void ApplyProjectSettings(AppSettings settings, DisasmProject project) {
|
||||
// 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
|
||||
// desired value. Easier to just have a set of named features.
|
||||
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";
|
||||
|
||||
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)) {
|
||||
settings.SetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS, true);
|
||||
|
|
|
@ -75,8 +75,7 @@ namespace SourceGen.Tools.WpfGui {
|
|||
|
||||
public void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||
// Restore chart mode setting.
|
||||
ChartMode mode = (ChartMode)AppSettings.Global.GetEnum(
|
||||
AppSettings.A2SC_MODE, typeof(ChartMode), (int)ChartMode.HiRes1_L);
|
||||
ChartMode mode = AppSettings.Global.GetEnum(AppSettings.A2SC_MODE, ChartMode.HiRes1_L);
|
||||
int index = 0;
|
||||
for (int i = 0; i < ChartModeItems.Length; i++) {
|
||||
if (ChartModeItems[i].Mode == mode) {
|
||||
|
@ -107,7 +106,7 @@ namespace SourceGen.Tools.WpfGui {
|
|||
return;
|
||||
}
|
||||
|
||||
AppSettings.Global.SetEnum(AppSettings.A2SC_MODE, typeof(ChartMode), (int)item.Mode);
|
||||
AppSettings.Global.SetEnum(AppSettings.A2SC_MODE, item.Mode);
|
||||
|
||||
string text;
|
||||
switch (item.Mode) {
|
||||
|
|
|
@ -55,8 +55,7 @@ namespace SourceGen.Tools.WpfGui {
|
|||
|
||||
public void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||
// Restore chart mode setting.
|
||||
ChartMode mode = (ChartMode)AppSettings.Global.GetEnum(
|
||||
AppSettings.ASCCH_MODE, typeof(ChartMode), (int)ChartMode.Standard);
|
||||
ChartMode mode = AppSettings.Global.GetEnum(AppSettings.ASCCH_MODE, ChartMode.Standard);
|
||||
int index = 0;
|
||||
for (int i = 0; i < ChartModeItems.Length; i++) {
|
||||
if (ChartModeItems[i].Mode == mode) {
|
||||
|
@ -87,7 +86,7 @@ namespace SourceGen.Tools.WpfGui {
|
|||
return;
|
||||
}
|
||||
|
||||
AppSettings.Global.SetEnum(AppSettings.ASCCH_MODE, typeof(ChartMode), (int)item.Mode);
|
||||
AppSettings.Global.SetEnum(AppSettings.ASCCH_MODE, item.Mode);
|
||||
|
||||
//
|
||||
// Draw box contents.
|
||||
|
|
|
@ -111,8 +111,8 @@ namespace SourceGen.Tools.WpfGui {
|
|||
AsciiOnlyDump = AppSettings.Global.GetBool(AppSettings.HEXD_ASCII_ONLY, false);
|
||||
|
||||
// Restore conv mode setting.
|
||||
CharConvMode mode = (CharConvMode)AppSettings.Global.GetEnum(
|
||||
AppSettings.HEXD_CHAR_CONV, typeof(CharConvMode), (int)CharConvMode.Ascii);
|
||||
CharConvMode mode =
|
||||
AppSettings.Global.GetEnum(AppSettings.HEXD_CHAR_CONV, CharConvMode.Ascii);
|
||||
int index = 0;
|
||||
for (int i = 0; i < CharConvItems.Length; i++) {
|
||||
if (CharConvItems[i].Mode == mode) {
|
||||
|
@ -156,8 +156,7 @@ namespace SourceGen.Tools.WpfGui {
|
|||
|
||||
// Keep app settings up to date.
|
||||
AppSettings.Global.SetBool(AppSettings.HEXD_ASCII_ONLY, mAsciiOnlyDump);
|
||||
AppSettings.Global.SetEnum(AppSettings.HEXD_CHAR_CONV, typeof(CharConvMode),
|
||||
(int)item.Mode);
|
||||
AppSettings.Global.SetEnum(AppSettings.HEXD_CHAR_CONV, item.Mode);
|
||||
|
||||
mFormatter = new Formatter(config);
|
||||
HexDumpLines.Reformat(mFormatter);
|
||||
|
|
|
@ -112,8 +112,8 @@ namespace SourceGen.Tools.WpfGui {
|
|||
|
||||
public void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||
// Restore chart settings.
|
||||
CpuDef.CpuType type = (CpuDef.CpuType)AppSettings.Global.GetEnum(
|
||||
AppSettings.INSTCH_MODE, typeof(CpuDef.CpuType), (int)CpuDef.CpuType.Cpu6502);
|
||||
CpuDef.CpuType type =
|
||||
AppSettings.Global.GetEnum(AppSettings.INSTCH_MODE, CpuDef.CpuType.Cpu6502);
|
||||
ShowUndocumented = AppSettings.Global.GetBool(AppSettings.INSTCH_SHOW_UNDOC, true);
|
||||
|
||||
int index = 0;
|
||||
|
@ -146,8 +146,7 @@ namespace SourceGen.Tools.WpfGui {
|
|||
}
|
||||
|
||||
// Push current choice to settings.
|
||||
AppSettings.Global.SetEnum(AppSettings.INSTCH_MODE, typeof(CpuDef.CpuType),
|
||||
(int)item.Type);
|
||||
AppSettings.Global.SetEnum(AppSettings.INSTCH_MODE, item.Type);
|
||||
AppSettings.Global.SetBool(AppSettings.INSTCH_SHOW_UNDOC, mShowUndocumented);
|
||||
|
||||
// Populate the items source.
|
||||
|
|
|
@ -820,10 +820,20 @@ limitations under the License.
|
|||
<TextBlock Text="General code generation:" Margin="4,16,0,0"/>
|
||||
<CheckBox Content="Show cycle counts in comments" Margin="4,8,0,0"
|
||||
IsChecked="{Binding ShowCycleCountsAsm}"/>
|
||||
<CheckBox Content="Put long labels on separate line" Margin="4,8,0,0"
|
||||
IsChecked="{Binding LongLabelNewLine}"/>
|
||||
<CheckBox Content="Identify assembler in output" Margin="4,8,0,0"
|
||||
<CheckBox Content="Identify assembler in output" Margin="4,6,0,0"
|
||||
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>
|
||||
</TabItem>
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ using CommonUtil;
|
|||
using AssemblerInfo = SourceGen.AsmGen.AssemblerInfo;
|
||||
using AssemblerConfig = SourceGen.AsmGen.AssemblerConfig;
|
||||
using ExpressionMode = Asm65.Formatter.FormatConfig.ExpressionMode;
|
||||
using LabelPlacement = SourceGen.AsmGen.GenCommon.LabelPlacement;
|
||||
|
||||
namespace SourceGen.WpfGui {
|
||||
/// <summary>
|
||||
|
@ -280,8 +281,8 @@ namespace SourceGen.WpfGui {
|
|||
UpperOperandXY = mSettings.GetBool(AppSettings.FMT_UPPER_OPERAND_XY, false);
|
||||
|
||||
Debug.Assert(clipboardFormatComboBox.Items.Count == sClipboardFormatItems.Length);
|
||||
int clipIndex = mSettings.GetEnum(AppSettings.CLIP_LINE_FORMAT,
|
||||
typeof(MainController.ClipLineFormat), 0);
|
||||
int clipIndex = (int)mSettings.GetEnum(AppSettings.CLIP_LINE_FORMAT,
|
||||
MainController.ClipLineFormat.AssemblerSource);
|
||||
if (clipIndex >= 0 && clipIndex < sClipboardFormatItems.Length) {
|
||||
// require Value == clipIndex because we're lazy and don't want to search
|
||||
Debug.Assert((int)sClipboardFormatItems[clipIndex].Value == clipIndex);
|
||||
|
@ -414,8 +415,7 @@ namespace SourceGen.WpfGui {
|
|||
private void ClipboardFormatComboBox_SelectionChanged(object sender,
|
||||
SelectionChangedEventArgs e) {
|
||||
ClipboardFormatItem item = (ClipboardFormatItem)clipboardFormatComboBox.SelectedItem;
|
||||
mSettings.SetEnum(AppSettings.CLIP_LINE_FORMAT, typeof(MainController.ClipLineFormat),
|
||||
(int)item.Value);
|
||||
mSettings.SetEnum(AppSettings.CLIP_LINE_FORMAT, item.Value);
|
||||
IsDirty = true;
|
||||
}
|
||||
|
||||
|
@ -757,14 +757,6 @@ namespace SourceGen.WpfGui {
|
|||
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 {
|
||||
get { return mSettings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false); }
|
||||
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() {
|
||||
asmConfigComboBox.SelectedItem = AssemblerInfo.GetAssemblerInfo(mInitialAsmId);
|
||||
if (asmConfigComboBox.SelectedIndex < 0) {
|
||||
|
|
|
@ -293,8 +293,7 @@ namespace SourceGen.WpfGui {
|
|||
AnalyzeStringRanges(item.Mode);
|
||||
UpdateControls();
|
||||
|
||||
AppSettings.Global.SetEnum(AppSettings.OPED_DEFAULT_STRING_ENCODING,
|
||||
typeof(TextScanMode), (int)item.Mode);
|
||||
AppSettings.Global.SetEnum(AppSettings.OPED_DEFAULT_STRING_ENCODING, item.Mode);
|
||||
}
|
||||
|
||||
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
|
||||
// doesn't specify a string, we'll use this.
|
||||
TextScanMode textMode = (TextScanMode)AppSettings.Global.GetEnum(
|
||||
AppSettings.OPED_DEFAULT_STRING_ENCODING, typeof(TextScanMode),
|
||||
(int)TextScanMode.LowHighAscii);
|
||||
TextScanMode textMode = AppSettings.Global.GetEnum(
|
||||
AppSettings.OPED_DEFAULT_STRING_ENCODING, TextScanMode.LowHighAscii);
|
||||
|
||||
if (dfd == null) {
|
||||
radioDefaultFormat.IsChecked = true;
|
||||
|
|
|
@ -20,9 +20,9 @@ using System.IO;
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using Microsoft.Win32;
|
||||
|
||||
using CommonUtil;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace SourceGen.WpfGui {
|
||||
/// <summary>
|
||||
|
@ -235,8 +235,8 @@ namespace SourceGen.WpfGui {
|
|||
AsmCommentColWidth = colWidths[3];
|
||||
}
|
||||
|
||||
TextMode mode = (TextMode)AppSettings.Global.GetEnum(AppSettings.EXPORT_TEXT_MODE,
|
||||
typeof(TextMode), (int)TextMode.PlainText);
|
||||
TextMode mode = AppSettings.Global.GetEnum(AppSettings.EXPORT_TEXT_MODE,
|
||||
TextMode.PlainText);
|
||||
if (mode == TextMode.PlainText) {
|
||||
TextModePlain = true;
|
||||
} else {
|
||||
|
@ -273,7 +273,7 @@ namespace SourceGen.WpfGui {
|
|||
} else {
|
||||
mode = TextMode.Csv;
|
||||
}
|
||||
AppSettings.Global.SetEnum(AppSettings.EXPORT_TEXT_MODE, typeof(TextMode), (int)mode);
|
||||
AppSettings.Global.SetEnum(AppSettings.EXPORT_TEXT_MODE, mode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<!--
|
||||
Copyright 2024 faddenSoft
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<Window x:Class="SourceGen.WpfGui.GenerateLabels"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:SourceGen.WpfGui"
|
||||
mc:Ignorable="d"
|
||||
Title="Generate Label File"
|
||||
SizeToContent="WidthAndHeight" ResizeMode="NoResize"
|
||||
ShowInTaskbar="False" WindowStartupLocation="CenterOwner">
|
||||
|
||||
<Grid Margin="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<GroupBox Grid.Row="0" Header="Output Format" Padding="2,4">
|
||||
<StackPanel>
|
||||
<RadioButton Content="VICE label commands"
|
||||
ToolTip="Load in VICE monitor with 'll' command."
|
||||
IsChecked="{Binding Format_VICE}"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<CheckBox Grid.Row="1" Margin="0,4,0,0" Content="Include auto-generated labels"
|
||||
IsChecked="{Binding IncludeAutoLabels}"/>
|
||||
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal"
|
||||
HorizontalAlignment="Right" Margin="0,8,0,0">
|
||||
<Button Content="Generate" IsDefault="True" Width="70" Click="OkButton_Click"/>
|
||||
<Button Content="Cancel" IsCancel="True" Width="70" Margin="4,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright 2019 faddenSoft
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace SourceGen.WpfGui {
|
||||
/// <summary>
|
||||
/// Select parameters for label file generation.
|
||||
/// </summary>
|
||||
public partial class GenerateLabels : Window, INotifyPropertyChanged {
|
||||
// INotifyPropertyChanged implementation
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
private void OnPropertyChanged([CallerMemberName] string propertyName = "") {
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public bool IncludeAutoLabels {
|
||||
get { return mIncludeAutoLabels; }
|
||||
set { mIncludeAutoLabels = value; OnPropertyChanged(); }
|
||||
}
|
||||
private bool mIncludeAutoLabels;
|
||||
|
||||
public LabelFileGenerator.LabelFmt Format { get; private set; }
|
||||
|
||||
public bool Format_VICE {
|
||||
get { return Format == LabelFileGenerator.LabelFmt.VICE;}
|
||||
set { Format = LabelFileGenerator.LabelFmt.VICE; UpdateFormats(); }
|
||||
}
|
||||
|
||||
private void UpdateFormats() {
|
||||
OnPropertyChanged(nameof(Format_VICE));
|
||||
}
|
||||
|
||||
|
||||
public GenerateLabels(Window owner) {
|
||||
InitializeComponent();
|
||||
Owner = owner;
|
||||
DataContext = this;
|
||||
|
||||
Format = AppSettings.Global.GetEnum(AppSettings.LABGEN_FORMAT,
|
||||
LabelFileGenerator.LabelFmt.VICE);
|
||||
UpdateFormats();
|
||||
mIncludeAutoLabels = AppSettings.Global.GetBool(AppSettings.LABGEN_INCLUDE_AUTO, false);
|
||||
}
|
||||
|
||||
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
||||
// Save settings.
|
||||
AppSettings.Global.SetEnum(AppSettings.LABGEN_FORMAT, Format);
|
||||
AppSettings.Global.SetBool(AppSettings.LABGEN_INCLUDE_AUTO, mIncludeAutoLabels);
|
||||
DialogResult = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -136,6 +136,7 @@ limitations under the License.
|
|||
</RoutedUICommand.InputGestures>
|
||||
</RoutedUICommand>
|
||||
<RoutedUICommand x:Key="FormatAddressTableCmd" Text="Format Address Table..."/>
|
||||
<RoutedUICommand x:Key="GenerateLabelsCmd" Text="Generate Label File..."/>
|
||||
<RoutedUICommand x:Key="GotoCmd" Text="Go To...">
|
||||
<RoutedUICommand.InputGestures>
|
||||
<KeyGesture>Ctrl+G</KeyGesture>
|
||||
|
@ -284,6 +285,8 @@ limitations under the License.
|
|||
CanExecute="CanFormatAsWord" Executed="FormatAsWordCmd_Executed"/>
|
||||
<CommandBinding Command="{StaticResource FormatAddressTableCmd}"
|
||||
CanExecute="CanFormatAddressTable" Executed="FormatAddressTableCmd_Executed"/>
|
||||
<CommandBinding Command="{StaticResource GenerateLabelsCmd}"
|
||||
CanExecute="IsProjectOpen" Executed="GenerateLabelsCmd_Executed"/>
|
||||
<CommandBinding Command="{StaticResource GotoCmd}"
|
||||
CanExecute="IsProjectOpen" Executed="GotoCmd_Executed"/>
|
||||
<CommandBinding Command="{StaticResource GotoLastChangeCmd}"
|
||||
|
@ -392,8 +395,8 @@ limitations under the License.
|
|||
</MenuItem>
|
||||
<Separator/>
|
||||
<MenuItem Command="{StaticResource AssembleCmd}"/>
|
||||
<!--<MenuItem Command="Print"/>-->
|
||||
<MenuItem Command="{StaticResource ExportCmd}"/>
|
||||
<MenuItem Command="{StaticResource GenerateLabelsCmd}"/>
|
||||
<Separator/>
|
||||
<MenuItem Command="{StaticResource ReloadExternalFilesCmd}"/>
|
||||
<Separator/>
|
||||
|
|
|
@ -1332,6 +1332,10 @@ namespace SourceGen.WpfGui {
|
|||
mMainCtrl.FormatAddressTable();
|
||||
}
|
||||
|
||||
private void GenerateLabelsCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
|
||||
mMainCtrl.GenerateLabels();
|
||||
}
|
||||
|
||||
private void GotoCmd_Executed(object sender, ExecutedRoutedEventArgs e) {
|
||||
mMainCtrl.Goto();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue