mirror of
https://github.com/fadden/6502bench.git
synced 2024-12-01 22:50:35 +00:00
Make operand wrap length configurable
Long operands, such as strings and bulk data, can span multiple lines. SourceGen wraps them at 64 characters, which is fine for assembly output but occasionally annoying on screen: if the operand column is wide enough to show the entire value, the comment column is pushed pretty far to the right. This change makes the width configurable, as 32/48/64 characters, with a pop-up in app settings. The assemblers are all wired to 64 characters, though we could make this configurable as well with an assembler-specific setting. Some things have moved around a bit in app settings. The Asm Config tab now comes last. Having it sandwiched in the middle of tabs that altered the on-screen display didn't make much sense. The Display Format is now explicitly for opcodes and operands, and is split into two columns. The left column is managed by the "quick set" feature, the right column is independent.
This commit is contained in:
parent
a3c7cd0cf9
commit
cb6ceafd73
@ -42,6 +42,10 @@ namespace Asm65 {
|
||||
/// fixed by keying off of the OpDef instead of OpDef.Opcode, but that's less convenient.)
|
||||
/// </summary>
|
||||
public class Formatter {
|
||||
// Default wrap point for long operands. This potentially affects both on-screen
|
||||
// display and source code generation.
|
||||
private const int DEFAULT_OPERAND_WRAP_LEN = 64;
|
||||
|
||||
/// <summary>
|
||||
/// Various format configuration options. Fill one of these out and pass it to
|
||||
/// the Formatter constructor.
|
||||
@ -80,6 +84,9 @@ namespace Asm65 {
|
||||
public DelimiterSet mCharDelimiters;
|
||||
public DelimiterSet mStringDelimiters;
|
||||
|
||||
// point at which we wrap long operands; zero uses default
|
||||
public int mOperandWrapLen;
|
||||
|
||||
// miscellaneous
|
||||
public bool mSpacesBetweenBytes; // "20edfd" vs. "20 ed fd"
|
||||
public bool mCommaSeparatedDense; // "20edfd" vs. "$20,$ed,$fd"
|
||||
@ -147,6 +154,10 @@ namespace Asm65 {
|
||||
if (mBoxLineCommentDelimiter == null) {
|
||||
mBoxLineCommentDelimiter = string.Empty;
|
||||
}
|
||||
|
||||
if (mOperandWrapLen == 0) {
|
||||
mOperandWrapLen = DEFAULT_OPERAND_WRAP_LEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -421,6 +432,13 @@ namespace Asm65 {
|
||||
get { return mFormatConfig.mExpressionMode; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Point at which to wrap long operands, such as strings and dense hex.
|
||||
/// </summary>
|
||||
public int OperandWrapLen {
|
||||
get { return mFormatConfig.mOperandWrapLen; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor. Initializes various fields based on the configuration. We want to
|
||||
|
@ -79,12 +79,11 @@ namespace Asm65 {
|
||||
/// <param name="formatter">Reference to text formatter.</param>
|
||||
/// <param name="delimiterDef">String delimiter values.</param>
|
||||
/// <param name="byteStyle">How to format raw byte data.</param>
|
||||
/// <param name="maxOperandLen">Maximum line length.</param>
|
||||
/// <param name="charConv">Character conversion delegate.</param>
|
||||
public StringOpFormatter(Formatter formatter, Formatter.DelimiterDef delimiterDef,
|
||||
RawOutputStyle byteStyle, int maxOperandLen, CharEncoding.Convert charConv) {
|
||||
RawOutputStyle byteStyle, CharEncoding.Convert charConv) {
|
||||
mRawStyle = byteStyle;
|
||||
mMaxOperandLen = maxOperandLen;
|
||||
mMaxOperandLen = formatter.OperandWrapLen;
|
||||
CharConv = charConv;
|
||||
|
||||
mDelimiterDef = delimiterDef;
|
||||
|
@ -56,6 +56,7 @@ namespace SourceGen {
|
||||
public const string FMT_UPPER_OPERAND_XY = "fmt-upper-operand-xy";
|
||||
public const string FMT_ADD_SPACE_FULL_COMMENT = "fmt-add-space-full-comment";
|
||||
public const string FMT_SPACES_BETWEEN_BYTES = "fmt-spaces-between-bytes";
|
||||
public const string FMT_OPERAND_WRAP_LEN = "fmt-operand-wrap-len";
|
||||
|
||||
public const string FMT_OPCODE_SUFFIX_ABS = "fmt-opcode-suffix-abs";
|
||||
public const string FMT_OPCODE_SUFFIX_LONG = "fmt-opcode-suffix-long";
|
||||
|
@ -37,7 +37,6 @@ namespace SourceGen.AsmGen {
|
||||
// makefile rules. Since ".S" is pretty universal for assembly language sources,
|
||||
// I'm sticking with that.
|
||||
private const string ASM_FILE_SUFFIX = "_acme.S"; // must start with underscore
|
||||
private const int MAX_OPERAND_LEN = 64;
|
||||
private const string CLOSE_PSEUDOPC = "} ;!pseudopc";
|
||||
|
||||
// IGenerator
|
||||
@ -185,6 +184,7 @@ namespace SourceGen.AsmGen {
|
||||
private void SetFormatConfigValues(ref Formatter.FormatConfig config) {
|
||||
config.mSuppressImpliedAcc = true;
|
||||
|
||||
config.mOperandWrapLen = 64;
|
||||
config.mForceDirectOpcodeSuffix = "+1";
|
||||
config.mForceAbsOpcodeSuffix = "+2";
|
||||
config.mForceLongOpcodeSuffix = "+3";
|
||||
@ -455,7 +455,7 @@ namespace SourceGen.AsmGen {
|
||||
private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) {
|
||||
Formatter formatter = SourceFormatter;
|
||||
byte[] data = Project.FileData;
|
||||
int maxPerLine = MAX_OPERAND_LEN / formatter.CharsPerDenseByte;
|
||||
int maxPerLine = formatter.OperandWrapLen / formatter.CharsPerDenseByte;
|
||||
|
||||
string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense);
|
||||
for (int i = 0; i < length; i += maxPerLine) {
|
||||
@ -648,8 +648,7 @@ namespace SourceGen.AsmGen {
|
||||
}
|
||||
|
||||
StringOpFormatter stropf = new StringOpFormatter(SourceFormatter,
|
||||
Formatter.DOUBLE_QUOTE_DELIM,StringOpFormatter.RawOutputStyle.CommaSep,
|
||||
MAX_OPERAND_LEN, charConv);
|
||||
Formatter.DOUBLE_QUOTE_DELIM,StringOpFormatter.RawOutputStyle.CommaSep, charConv);
|
||||
stropf.FeedBytes(data, offset, dfd.Length, leadingBytes,
|
||||
StringOpFormatter.ReverseMode.Forward);
|
||||
|
||||
|
@ -32,7 +32,6 @@ namespace SourceGen.AsmGen {
|
||||
public class GenCc65 : IGenerator {
|
||||
private const string ASM_FILE_SUFFIX = "_cc65.S"; // must start with underscore
|
||||
private const string CFG_FILE_SUFFIX = "_cc65.cfg"; // ditto
|
||||
private const int MAX_OPERAND_LEN = 64;
|
||||
|
||||
// IGenerator
|
||||
public DisasmProject Project { get; private set; }
|
||||
@ -181,6 +180,7 @@ namespace SourceGen.AsmGen {
|
||||
/// Configures the assembler-specific format items.
|
||||
/// </summary>
|
||||
private void SetFormatConfigValues(ref Formatter.FormatConfig config) {
|
||||
config.mOperandWrapLen = 64;
|
||||
config.mForceDirectOpcodeSuffix = string.Empty;
|
||||
config.mForceAbsOpcodeSuffix = string.Empty;
|
||||
config.mForceLongOpcodeSuffix = string.Empty;
|
||||
@ -486,7 +486,7 @@ namespace SourceGen.AsmGen {
|
||||
private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) {
|
||||
Formatter formatter = SourceFormatter;
|
||||
byte[] data = Project.FileData;
|
||||
int maxPerLine = MAX_OPERAND_LEN / formatter.CharsPerDenseByte;
|
||||
int maxPerLine = formatter.OperandWrapLen / formatter.CharsPerDenseByte;
|
||||
|
||||
string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense);
|
||||
for (int i = 0; i < length; i += maxPerLine) {
|
||||
@ -709,8 +709,7 @@ namespace SourceGen.AsmGen {
|
||||
}
|
||||
|
||||
StringOpFormatter stropf = new StringOpFormatter(SourceFormatter,
|
||||
Formatter.DOUBLE_QUOTE_DELIM, StringOpFormatter.RawOutputStyle.CommaSep,
|
||||
MAX_OPERAND_LEN, charConv);
|
||||
Formatter.DOUBLE_QUOTE_DELIM, StringOpFormatter.RawOutputStyle.CommaSep, charConv);
|
||||
stropf.FeedBytes(data, offset, dfd.Length - trailingBytes, leadingBytes,
|
||||
StringOpFormatter.ReverseMode.Forward);
|
||||
|
||||
|
@ -32,7 +32,6 @@ namespace SourceGen.AsmGen {
|
||||
/// </summary>
|
||||
public class GenMerlin32 : IGenerator {
|
||||
private const string ASM_FILE_SUFFIX = "_Merlin32.S"; // must start with underscore
|
||||
private const int MAX_OPERAND_LEN = 64;
|
||||
|
||||
// IGenerator
|
||||
public DisasmProject Project { get; private set; }
|
||||
@ -155,6 +154,7 @@ namespace SourceGen.AsmGen {
|
||||
/// Configures the assembler-specific format items.
|
||||
/// </summary>
|
||||
private void SetFormatConfigValues(ref Formatter.FormatConfig config) {
|
||||
config.mOperandWrapLen = 64;
|
||||
config.mForceDirectOpcodeSuffix = string.Empty;
|
||||
config.mForceAbsOpcodeSuffix = ":";
|
||||
config.mForceLongOpcodeSuffix = "l";
|
||||
@ -333,7 +333,7 @@ namespace SourceGen.AsmGen {
|
||||
private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) {
|
||||
Formatter formatter = SourceFormatter;
|
||||
byte[] data = Project.FileData;
|
||||
int maxPerLine = MAX_OPERAND_LEN / formatter.CharsPerDenseByte;
|
||||
int maxPerLine = formatter.OperandWrapLen / formatter.CharsPerDenseByte;
|
||||
|
||||
string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense);
|
||||
for (int i = 0; i < length; i += maxPerLine) {
|
||||
@ -607,7 +607,7 @@ namespace SourceGen.AsmGen {
|
||||
|
||||
StringOpFormatter stropf = new StringOpFormatter(SourceFormatter,
|
||||
new Formatter.DelimiterDef(delim),
|
||||
StringOpFormatter.RawOutputStyle.DenseHex, MAX_OPERAND_LEN, charConv);
|
||||
StringOpFormatter.RawOutputStyle.DenseHex, charConv);
|
||||
if (dfd.FormatType == FormatDescriptor.Type.StringDci) {
|
||||
// DCI is awkward because the character encoding flips on the last byte. Rather
|
||||
// than clutter up StringOpFormatter for this rare item, we just accept low/high
|
||||
|
@ -45,7 +45,6 @@ namespace SourceGen.AsmGen {
|
||||
private const string ASM_FILE_SUFFIX = "_64tass.S"; // must start with underscore
|
||||
private const string ASCII_ENC_NAME = "sg_ascii";
|
||||
private const string HIGH_ASCII_ENC_NAME = "sg_hiascii";
|
||||
private const int MAX_OPERAND_LEN = 64;
|
||||
|
||||
// IGenerator
|
||||
public DisasmProject Project { get; private set; }
|
||||
@ -188,6 +187,7 @@ namespace SourceGen.AsmGen {
|
||||
config.mUpperOperandA = false;
|
||||
config.mUpperOperandS = false;
|
||||
config.mUpperOperandXY = false;
|
||||
config.mOperandWrapLen = 64;
|
||||
|
||||
config.mBankSelectBackQuote = true;
|
||||
|
||||
@ -524,7 +524,7 @@ namespace SourceGen.AsmGen {
|
||||
private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) {
|
||||
Formatter formatter = SourceFormatter;
|
||||
byte[] data = Project.FileData;
|
||||
int maxPerLine = MAX_OPERAND_LEN / formatter.CharsPerDenseByte;
|
||||
int maxPerLine = formatter.OperandWrapLen / formatter.CharsPerDenseByte;
|
||||
|
||||
string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense);
|
||||
for (int i = 0; i < length; i += maxPerLine) {
|
||||
@ -744,8 +744,7 @@ namespace SourceGen.AsmGen {
|
||||
}
|
||||
|
||||
StringOpFormatter stropf = new StringOpFormatter(SourceFormatter,
|
||||
Formatter.DOUBLE_QUOTE_DELIM,StringOpFormatter.RawOutputStyle.CommaSep,
|
||||
MAX_OPERAND_LEN, charConv);
|
||||
Formatter.DOUBLE_QUOTE_DELIM,StringOpFormatter.RawOutputStyle.CommaSep, charConv);
|
||||
if (dfd.FormatType == FormatDescriptor.Type.StringDci) {
|
||||
// DCI is awkward because the character encoding flips on the last byte. Rather
|
||||
// than clutter up StringOpFormatter for this rare item, we just accept low/high
|
||||
|
@ -425,6 +425,8 @@ namespace SourceGen.AsmGen {
|
||||
settings.GetBool(AppSettings.FMT_SPACES_BETWEEN_BYTES, false);
|
||||
config.mAddSpaceLongComment =
|
||||
settings.GetBool(AppSettings.FMT_ADD_SPACE_FULL_COMMENT, true);
|
||||
config.mOperandWrapLen =
|
||||
settings.GetInt(AppSettings.FMT_OPERAND_WRAP_LEN, 0);
|
||||
|
||||
config.mForceAbsOpcodeSuffix =
|
||||
settings.GetString(AppSettings.FMT_OPCODE_SUFFIX_ABS, string.Empty);
|
||||
|
@ -33,8 +33,6 @@ namespace SourceGen {
|
||||
/// multiple lines.
|
||||
/// </summary>
|
||||
public class PseudoOp {
|
||||
private const int MAX_OPERAND_LEN = 64;
|
||||
|
||||
/// <summary>
|
||||
/// One piece of the pseudo-instruction.
|
||||
/// </summary>
|
||||
@ -278,7 +276,7 @@ namespace SourceGen {
|
||||
return 1;
|
||||
case FormatDescriptor.Type.Dense: {
|
||||
// no delimiter, two output bytes per input byte
|
||||
int maxLen = MAX_OPERAND_LEN;
|
||||
int maxLen = formatter.OperandWrapLen;
|
||||
int textLen = dfd.Length * formatter.CharsPerDenseByte;
|
||||
return (textLen + maxLen - 1) / maxLen;
|
||||
}
|
||||
@ -367,7 +365,7 @@ namespace SourceGen {
|
||||
}
|
||||
break;
|
||||
case FormatDescriptor.Type.Dense: {
|
||||
int maxPerLine = MAX_OPERAND_LEN / formatter.CharsPerDenseByte;
|
||||
int maxPerLine = formatter.OperandWrapLen / formatter.CharsPerDenseByte;
|
||||
offset += subIndex * maxPerLine;
|
||||
length -= subIndex * maxPerLine;
|
||||
if (length > maxPerLine) {
|
||||
@ -547,7 +545,7 @@ namespace SourceGen {
|
||||
}
|
||||
|
||||
StringOpFormatter stropf = new StringOpFormatter(formatter, delDef,
|
||||
StringOpFormatter.RawOutputStyle.CommaSep, MAX_OPERAND_LEN, charConv);
|
||||
StringOpFormatter.RawOutputStyle.CommaSep, charConv);
|
||||
stropf.FeedBytes(data, offset + hiddenLeadingBytes,
|
||||
dfd.Length - hiddenLeadingBytes - trailingBytes, 0, revMode);
|
||||
|
||||
|
@ -100,6 +100,65 @@ do not affect generated code, which must use the delimiter characters
|
||||
specified by the chosen assembler.</p>
|
||||
|
||||
|
||||
<h3><a name="appset-displayformat">Display Format</a></h3>
|
||||
|
||||
<p>These options change the way the code list looks on screen. They
|
||||
do not affect generated code.</p>
|
||||
|
||||
<p>The
|
||||
<a href="intro.html#width-disambiguation">operand width disambiguator</a>
|
||||
strings are used when the width of an instruction operand is unclear.
|
||||
You may specify values for all of them or none of them.</p>
|
||||
|
||||
<p>Different assemblers have different ways of forming expressions.
|
||||
Sometimes the rules allow expressions to be written simply, other times
|
||||
explicit grouping with parenthesis is required. Select whichever style
|
||||
you are most comfortable with.</p>
|
||||
|
||||
<p>Non-unique labels are identified with a prefix character, typically
|
||||
'@' or ':'. The default is '@', but you can configure it to any character
|
||||
that isn't valid for the start of a label. (64tass uses '_' for locals,
|
||||
but that's a valid label start character, and so isn't allowed here.)
|
||||
The setting affects label editing as well as display.</p>
|
||||
|
||||
<p>If you would like your local variables to be shown with a prefix
|
||||
character, you can set it in the "local variable prefix" box.</p>
|
||||
|
||||
<p>The "quick set" pop-up configures the fields on the left side of the
|
||||
tab to match the conventions of the specified assembler. Select your
|
||||
preferred assembler in the combo box to set the fields. The setting
|
||||
automatically switches to "custom" when you edit a field.
|
||||
(64tass and ACME use the "common"
|
||||
expression style, cc65 and Merlin 32 have their own unique styles.)</p>
|
||||
|
||||
<p>The "comma-separated format for bulk data" determines whether large
|
||||
blocks of hex look like <code>ABC123</code> or
|
||||
<code>$AB,$C1,$23</code>. The former reduces the number of lines
|
||||
required, the latter is more readable.</p>
|
||||
<p>Long operands, such as strings and bulk data, are wrapped to a new
|
||||
line after a certain number of characters. Use the pop-up to configure
|
||||
the value. Larger values can make the code easier to read, but smaller
|
||||
values allow you to shrink the width of the operand column in the
|
||||
on-screen listing, moving the comment field closer in.</p>
|
||||
|
||||
|
||||
<h3><a name="appset-pseudoop">Pseudo-Op</a></h3>
|
||||
|
||||
<p>These options change the way the code list looks on screen. Assembler
|
||||
directives and data pseudo-opcodes will use these values. This does
|
||||
not affect generated source code, which always matches the conventions
|
||||
of the target assembler.</p>
|
||||
|
||||
<p>Enter the string you want to use for the various data formats. If
|
||||
a field is left blank, a default value is used.</p>
|
||||
|
||||
<p>The "quick set" pop-up configures the fields on this tab to match
|
||||
the conventions of the specified assembler. Select your preferred assembler
|
||||
in the combo box to set the fields. The setting automatically switches to
|
||||
"custom" when you edit a field.</p>
|
||||
|
||||
|
||||
|
||||
<h3><a name="appset-asmconfig">Asm Config</a></h3>
|
||||
|
||||
<p>These settings configure cross-assemblers and modify assembly source
|
||||
@ -150,53 +209,6 @@ the source file what the intended target assembler is, or what options
|
||||
are required to process the file correctly.</p>
|
||||
|
||||
|
||||
<h3><a name="appset-displayformat">Display Format</a></h3>
|
||||
|
||||
<p>These options change the way the code list looks on screen. They
|
||||
do not affect generated code.</p>
|
||||
|
||||
<p>The
|
||||
<a href="intro.html#width-disambiguation">operand width disambiguator</a>
|
||||
strings are used when the width of an instruction operand is unclear.
|
||||
You may specify values for all of them or none of them.</p>
|
||||
|
||||
<p>Different assemblers have different ways of forming expressions.
|
||||
Sometimes the rules allow expressions to be written simply, other times
|
||||
explicit grouping with parenthesis is required. Select whichever style
|
||||
you are most comfortable with.</p>
|
||||
|
||||
<p>Non-unique labels are identified with a prefix character, typically
|
||||
'@' or ':'. The default is '@', but you can configure it to any character
|
||||
that isn't valid for the start of a label. (64tass uses '_' for locals,
|
||||
but that's a valid label start character, and so isn't allowed here.)
|
||||
The setting affects label editing as well as display.</p>
|
||||
|
||||
<p>If you would like your local variables to be shown with a prefix
|
||||
character, you can set it in the "local variable prefix" box.</p>
|
||||
|
||||
<p>The "quick set" pop-up configures the fields on this tab to match
|
||||
the conventions of the specified assembler. Select your preferred assembler
|
||||
in the combo box to set the fields. The setting automatically switches to
|
||||
"custom" when you edit a field. (64tass and ACME use the "common"
|
||||
expression style, cc65 and Merlin 32 have their own unique styles.)</p>
|
||||
|
||||
|
||||
<h3><a name="appset-pseudoop">Pseudo-Op</a></h3>
|
||||
|
||||
<p>These options change the way the code list looks on screen. Assembler
|
||||
directives and data pseudo-opcodes will use these values. This does
|
||||
not affect generated source code, which always matches the conventions
|
||||
of the target assembler.</p>
|
||||
|
||||
<p>Enter the string you want to use for the various data formats. If
|
||||
a field is left blank, a default value is used.</p>
|
||||
|
||||
<p>The "quick set" pop-up configures the fields on this tab to match
|
||||
the conventions of the specified assembler. Select your preferred assembler
|
||||
in the combo box to set the fields. The setting automatically switches to
|
||||
"custom" when you edit a field.</p>
|
||||
|
||||
|
||||
<h2><a name="project-properties">Project Properties</a></h2>
|
||||
|
||||
<p>Project properties are stored in the .dis65 project file.
|
||||
|
@ -389,6 +389,7 @@ namespace SourceGen.Tests {
|
||||
settings.SetBool(AppSettings.FMT_UPPER_OPERAND_S, true);
|
||||
settings.SetBool(AppSettings.FMT_UPPER_OPERAND_XY, false);
|
||||
settings.SetBool(AppSettings.FMT_ADD_SPACE_FULL_COMMENT, false);
|
||||
settings.SetInt(AppSettings.FMT_OPERAND_WRAP_LEN, 64);
|
||||
|
||||
// Don't show the assembler ident line. You can make a case for this being
|
||||
// mandatory, since the generated code is only guaranteed to work with the
|
||||
|
@ -129,10 +129,10 @@ limitations under the License.
|
||||
<GroupBox Grid.Column="2" Grid.Row="1" Header="Miscellaneous"
|
||||
Margin="10,0,0,0" Padding="2,4">
|
||||
<StackPanel>
|
||||
<CheckBox Content="Add spaces in bytes column" Margin="0,4"
|
||||
IsChecked="{Binding SpacesBetweenBytes}"/>
|
||||
<CheckBox Content="Use "dark" color scheme" Margin="0,4"
|
||||
IsChecked="{Binding DarkColorScheme}"/>
|
||||
<CheckBox Content="Add spaces in bytes column" Margin="0,4"
|
||||
IsChecked="{Binding SpacesBetweenBytes}"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
@ -422,95 +422,21 @@ limitations under the License.
|
||||
</TabItem>
|
||||
|
||||
|
||||
<TabItem Name="asmConfigTab" Header="Asm Config">
|
||||
<StackPanel>
|
||||
<GroupBox Header="Assembler Configuration" Padding="2,4">
|
||||
<TabItem Name="displayFormatTab" Header="Display Format">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Text="Assembler:"
|
||||
HorizontalAlignment="Right" Margin="0,5,4,0"/>
|
||||
<ComboBox Name="asmConfigComboBox" Grid.Column="1" Grid.Row="0" IsReadOnly="True"
|
||||
Width="150" HorizontalAlignment="Left" Margin="0,4,0,20"
|
||||
ItemsSource="{Binding AssemblerList}" DisplayMemberPath="Name"
|
||||
SelectionChanged="AsmConfigComboBox_SelectionChanged"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Text="Executable:"
|
||||
HorizontalAlignment="Right" Margin="0,0,4,0"/>
|
||||
<DockPanel Grid.Column="1" Grid.Row="1">
|
||||
<Button DockPanel.Dock="Right" Content="Browse..." Width="75"
|
||||
Margin="8,0,0,8" Click="AsmExeBrowseButton_Click"/>
|
||||
<TextBox Name="asmExePathTextBox" DockPanel.Dock="Left" Margin="0,0,0,8"
|
||||
Text="C:\something" TextChanged="AsmExePathTextBox_TextChanged"/>
|
||||
</DockPanel>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="2" Text="Column widths:"
|
||||
HorizontalAlignment="Right" Margin="0,0,4,0"/>
|
||||
<StackPanel Grid.Column="1" Grid.Row="2" Orientation="Horizontal">
|
||||
<TextBox Name="asmLabelColWidthTextBox" Width="60" Margin="0,0,4,0">
|
||||
<TextBox.Text>
|
||||
<Binding Path="AsmLabelColWidth" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
<TextBox Name="asmOpcodeColWidthTextBox" Width="60" Margin="0,0,4,0">
|
||||
<TextBox.Text>
|
||||
<Binding Path="AsmOpcodeColWidth" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
<TextBox Name="asmOperandColWidthTextBox" Width="60" Margin="0,0,4,0">
|
||||
<TextBox.Text>
|
||||
<Binding Path="AsmOperandColWidth" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
<TextBox Name="asmCommentColWidthTextBox" Width="60" Margin="0,0,8,0">
|
||||
<TextBox.Text>
|
||||
<Binding Path="AsmCommentColWidth" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
<TextBlock Text="(label, opcode, operand, comment)"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<TextBlock Text="General code generation:" Margin="4,16,0,0"/>
|
||||
<CheckBox Content="Show cycle counts (also appears on screen)" Margin="4,8,0,0"
|
||||
IsChecked="{Binding ShowCycleCounts}"/>
|
||||
<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"
|
||||
IsChecked="{Binding AddIdentComment}"/>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
|
||||
<TabItem Name="displayFormatTab" Header="Display Format">
|
||||
<DockPanel LastChildFill="False">
|
||||
<TextBlock DockPanel.Dock="Top" Margin="4,0,0,0"
|
||||
Text="Configure display format options. This does not affect source code generation."/>
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Margin="4,0,0,0"
|
||||
Text="Configure opcode/operand display format options. This does not affect source code generation."/>
|
||||
<DockPanel Grid.Column="0" Grid.Row="1" LastChildFill="False">
|
||||
<GroupBox Header="Operand Width Disambiguator" Width="300" DockPanel.Dock="Top"
|
||||
HorizontalAlignment="Left" Margin="0,8,0,0" Padding="2,0">
|
||||
<Grid>
|
||||
@ -560,7 +486,7 @@ limitations under the License.
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="4,16,0,0">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="4,8,0,0">
|
||||
<TextBlock Text="Expression style:" Margin="0,3,0,0"/>
|
||||
<ComboBox Name="expressionStyleComboBox" Width="120" Margin="8,0,0,0"
|
||||
ItemsSource="{Binding ExpressionStyleItems}" DisplayMemberPath="Name"
|
||||
@ -568,7 +494,7 @@ limitations under the License.
|
||||
SelectionChanged="ExpressionStyleComboBox_SelectionChanged"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="4,16,0,0">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="4,8,0,0">
|
||||
<TextBlock Text="Non-unique label prefix:"/>
|
||||
<TextBox Width="14" MaxLength="1" Margin="8,1,0,0"
|
||||
Text="{Binding NonUniqueLabelPrefix, UpdateSourceTrigger=PropertyChanged,
|
||||
@ -584,18 +510,32 @@ limitations under the License.
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
</StackPanel>
|
||||
|
||||
<CheckBox DockPanel.Dock="Top" Margin="4,6,0,0"
|
||||
Content="Use comma-separated format for bulk data"
|
||||
IsChecked="{Binding CommaSeparatedBulkData}"/>
|
||||
|
||||
<GroupBox DockPanel.Dock="Bottom" Header="Quick Set"
|
||||
HorizontalAlignment="Right" Padding="2,4">
|
||||
HorizontalAlignment="Left" Padding="2,4">
|
||||
<ComboBox Name="displayFmtQuickComboBox" DockPanel.Dock="Right"
|
||||
Width="170" IsReadOnly="True"
|
||||
ItemsSource="{Binding DisplayPresets}" DisplayMemberPath="Name"
|
||||
SelectionChanged="DisplayFmtQuickComboBox_SelectionChanged"/>
|
||||
</GroupBox>
|
||||
</DockPanel>
|
||||
|
||||
<Rectangle Grid.Column="1" Grid.Row="1" Margin="0,8,0,0"
|
||||
VerticalAlignment="Stretch" Fill="LightGray" Width="2"/>
|
||||
|
||||
<DockPanel Grid.Column="2" Grid.Row="1" LastChildFill="False">
|
||||
<CheckBox DockPanel.Dock="Top" Margin="4,12,0,0"
|
||||
Content="Use comma-separated format for bulk data"
|
||||
IsChecked="{Binding CommaSeparatedBulkData}"/>
|
||||
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="4,8,0,0">
|
||||
<TextBlock Text="Wrap operands at" Margin="0,3,0,0"/>
|
||||
<ComboBox Name="operandWrapLenComboBox" Width="45" Margin="4,0,0,0"
|
||||
ItemsSource="{Binding OperandWrapLenItems}" IsReadOnly="True"
|
||||
SelectionChanged="OperandWrapLenComboBox_SelectionChanged"/>
|
||||
<TextBlock Text="characters" Margin="4,3,0,0"/>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
|
||||
@ -775,6 +715,92 @@ limitations under the License.
|
||||
</GroupBox>
|
||||
</DockPanel>
|
||||
</TabItem>
|
||||
|
||||
|
||||
<TabItem Name="asmConfigTab" Header="Asm Config">
|
||||
<StackPanel>
|
||||
<GroupBox Header="Assembler Configuration" Padding="2,4">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Text="Assembler:"
|
||||
HorizontalAlignment="Right" Margin="0,5,4,0"/>
|
||||
<ComboBox Name="asmConfigComboBox" Grid.Column="1" Grid.Row="0" IsReadOnly="True"
|
||||
Width="150" HorizontalAlignment="Left" Margin="0,4,0,20"
|
||||
ItemsSource="{Binding AssemblerList}" DisplayMemberPath="Name"
|
||||
SelectionChanged="AsmConfigComboBox_SelectionChanged"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="1" Text="Executable:"
|
||||
HorizontalAlignment="Right" Margin="0,0,4,0"/>
|
||||
<DockPanel Grid.Column="1" Grid.Row="1">
|
||||
<Button DockPanel.Dock="Right" Content="Browse..." Width="75"
|
||||
Margin="8,0,0,8" Click="AsmExeBrowseButton_Click"/>
|
||||
<TextBox Name="asmExePathTextBox" DockPanel.Dock="Left" Margin="0,0,0,8"
|
||||
Text="C:\something" TextChanged="AsmExePathTextBox_TextChanged"/>
|
||||
</DockPanel>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="2" Text="Column widths:"
|
||||
HorizontalAlignment="Right" Margin="0,0,4,0"/>
|
||||
<StackPanel Grid.Column="1" Grid.Row="2" Orientation="Horizontal">
|
||||
<TextBox Name="asmLabelColWidthTextBox" Width="60" Margin="0,0,4,0">
|
||||
<TextBox.Text>
|
||||
<Binding Path="AsmLabelColWidth" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
<TextBox Name="asmOpcodeColWidthTextBox" Width="60" Margin="0,0,4,0">
|
||||
<TextBox.Text>
|
||||
<Binding Path="AsmOpcodeColWidth" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
<TextBox Name="asmOperandColWidthTextBox" Width="60" Margin="0,0,4,0">
|
||||
<TextBox.Text>
|
||||
<Binding Path="AsmOperandColWidth" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
<TextBox Name="asmCommentColWidthTextBox" Width="60" Margin="0,0,8,0">
|
||||
<TextBox.Text>
|
||||
<Binding Path="AsmCommentColWidth" UpdateSourceTrigger="PropertyChanged">
|
||||
<Binding.ValidationRules>
|
||||
<local:AsmColWidthRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
<TextBlock Text="(label, opcode, operand, comment)"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<TextBlock Text="General code generation:" Margin="4,16,0,0"/>
|
||||
<CheckBox Content="Show cycle counts (also appears on screen)" Margin="4,8,0,0"
|
||||
IsChecked="{Binding ShowCycleCounts}"/>
|
||||
<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"
|
||||
IsChecked="{Binding AddIdentComment}"/>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
</TabControl>
|
||||
</DockPanel>
|
||||
</Window>
|
||||
|
@ -74,9 +74,9 @@ namespace SourceGen.WpfGui {
|
||||
Unknown = 0,
|
||||
CodeView,
|
||||
TextDelimiters,
|
||||
AsmConfig,
|
||||
DisplayFormat,
|
||||
PseudoOp
|
||||
PseudoOp,
|
||||
AsmConfig
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -936,6 +936,25 @@ namespace SourceGen.WpfGui {
|
||||
};
|
||||
}
|
||||
|
||||
public class OperandWrapLenItem {
|
||||
public int Len { get; private set; }
|
||||
|
||||
public OperandWrapLenItem(int len) {
|
||||
Len = len;
|
||||
}
|
||||
public override string ToString() {
|
||||
return Len.ToString();
|
||||
}
|
||||
}
|
||||
private static OperandWrapLenItem[] sOperandWrapLenItems = {
|
||||
new OperandWrapLenItem(64),
|
||||
new OperandWrapLenItem(48),
|
||||
new OperandWrapLenItem(32)
|
||||
};
|
||||
public OperandWrapLenItem[] OperandWrapLenItems {
|
||||
get { return sOperandWrapLenItems; }
|
||||
}
|
||||
|
||||
public class DisplayFormatPreset {
|
||||
public const int ID_CUSTOM = -2;
|
||||
public const int ID_DEFAULT = -1;
|
||||
@ -1024,6 +1043,9 @@ namespace SourceGen.WpfGui {
|
||||
}
|
||||
SelectExpressionStyle(mode);
|
||||
|
||||
int wrapLen = mSettings.GetInt(AppSettings.FMT_OPERAND_WRAP_LEN, 0);
|
||||
SelectOperandWrapLen(wrapLen);
|
||||
|
||||
// No need to set this to anything specific.
|
||||
UpdateDisplayFormatQuickCombo();
|
||||
}
|
||||
@ -1038,10 +1060,30 @@ namespace SourceGen.WpfGui {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Debug.Assert(false, "Expression mode " + mode + " not found");
|
||||
Debug.Assert(false, "Expression mode " + mode + " not found in combo box");
|
||||
expressionStyleComboBox.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the combo box to a matching wrap length.
|
||||
/// </summary>
|
||||
private void SelectOperandWrapLen(int wrapLen) {
|
||||
if (wrapLen == 0) {
|
||||
// Setting wasn't specified, use first entry in list. For best results this
|
||||
// should match Formatter.DEFAULT_OPERAND_WRAP_LEN.
|
||||
operandWrapLenComboBox.SelectedIndex = 0;
|
||||
return;
|
||||
}
|
||||
foreach (OperandWrapLenItem owli in OperandWrapLenItems) {
|
||||
if (owli.Len == wrapLen) {
|
||||
operandWrapLenComboBox.SelectedItem = owli;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Debug.Assert(false, "Operand wrap len " + wrapLen + " not found in combo box");
|
||||
operandWrapLenComboBox.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles a change to the expression style.
|
||||
/// </summary>
|
||||
@ -1110,6 +1152,13 @@ namespace SourceGen.WpfGui {
|
||||
mSettingDisplayFmtCombo = false;
|
||||
}
|
||||
|
||||
private void OperandWrapLenComboBox_SelectionChanged(object sender,
|
||||
SelectionChangedEventArgs e) {
|
||||
OperandWrapLenItem item = (OperandWrapLenItem)operandWrapLenComboBox.SelectedItem;
|
||||
mSettings.SetInt(AppSettings.FMT_OPERAND_WRAP_LEN, item.Len);
|
||||
IsDirty = true;
|
||||
}
|
||||
|
||||
#endregion Display Format
|
||||
|
||||
#region PseudoOp
|
||||
|
Loading…
Reference in New Issue
Block a user