1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-12-02 13:51:36 +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:
Andy McFadden 2020-07-19 18:39:27 -07:00
parent a3c7cd0cf9
commit cb6ceafd73
13 changed files with 343 additions and 240 deletions

View File

@ -42,6 +42,10 @@ namespace Asm65 {
/// fixed by keying off of the OpDef instead of OpDef.Opcode, but that's less convenient.) /// fixed by keying off of the OpDef instead of OpDef.Opcode, but that's less convenient.)
/// </summary> /// </summary>
public class Formatter { 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> /// <summary>
/// Various format configuration options. Fill one of these out and pass it to /// Various format configuration options. Fill one of these out and pass it to
/// the Formatter constructor. /// the Formatter constructor.
@ -80,6 +84,9 @@ namespace Asm65 {
public DelimiterSet mCharDelimiters; public DelimiterSet mCharDelimiters;
public DelimiterSet mStringDelimiters; public DelimiterSet mStringDelimiters;
// point at which we wrap long operands; zero uses default
public int mOperandWrapLen;
// miscellaneous // miscellaneous
public bool mSpacesBetweenBytes; // "20edfd" vs. "20 ed fd" public bool mSpacesBetweenBytes; // "20edfd" vs. "20 ed fd"
public bool mCommaSeparatedDense; // "20edfd" vs. "$20,$ed,$fd" public bool mCommaSeparatedDense; // "20edfd" vs. "$20,$ed,$fd"
@ -147,6 +154,10 @@ namespace Asm65 {
if (mBoxLineCommentDelimiter == null) { if (mBoxLineCommentDelimiter == null) {
mBoxLineCommentDelimiter = string.Empty; mBoxLineCommentDelimiter = string.Empty;
} }
if (mOperandWrapLen == 0) {
mOperandWrapLen = DEFAULT_OPERAND_WRAP_LEN;
}
} }
} }
@ -421,6 +432,13 @@ namespace Asm65 {
get { return mFormatConfig.mExpressionMode; } 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> /// <summary>
/// Constructor. Initializes various fields based on the configuration. We want to /// Constructor. Initializes various fields based on the configuration. We want to

View File

@ -79,12 +79,11 @@ namespace Asm65 {
/// <param name="formatter">Reference to text formatter.</param> /// <param name="formatter">Reference to text formatter.</param>
/// <param name="delimiterDef">String delimiter values.</param> /// <param name="delimiterDef">String delimiter values.</param>
/// <param name="byteStyle">How to format raw byte data.</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> /// <param name="charConv">Character conversion delegate.</param>
public StringOpFormatter(Formatter formatter, Formatter.DelimiterDef delimiterDef, public StringOpFormatter(Formatter formatter, Formatter.DelimiterDef delimiterDef,
RawOutputStyle byteStyle, int maxOperandLen, CharEncoding.Convert charConv) { RawOutputStyle byteStyle, CharEncoding.Convert charConv) {
mRawStyle = byteStyle; mRawStyle = byteStyle;
mMaxOperandLen = maxOperandLen; mMaxOperandLen = formatter.OperandWrapLen;
CharConv = charConv; CharConv = charConv;
mDelimiterDef = delimiterDef; mDelimiterDef = delimiterDef;

View File

@ -56,6 +56,7 @@ namespace SourceGen {
public const string FMT_UPPER_OPERAND_XY = "fmt-upper-operand-xy"; 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_ADD_SPACE_FULL_COMMENT = "fmt-add-space-full-comment";
public const string FMT_SPACES_BETWEEN_BYTES = "fmt-spaces-between-bytes"; 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_ABS = "fmt-opcode-suffix-abs";
public const string FMT_OPCODE_SUFFIX_LONG = "fmt-opcode-suffix-long"; public const string FMT_OPCODE_SUFFIX_LONG = "fmt-opcode-suffix-long";

View File

@ -37,7 +37,6 @@ namespace SourceGen.AsmGen {
// makefile rules. Since ".S" is pretty universal for assembly language sources, // makefile rules. Since ".S" is pretty universal for assembly language sources,
// I'm sticking with that. // I'm sticking with that.
private const string ASM_FILE_SUFFIX = "_acme.S"; // must start with underscore 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"; private const string CLOSE_PSEUDOPC = "} ;!pseudopc";
// IGenerator // IGenerator
@ -185,6 +184,7 @@ namespace SourceGen.AsmGen {
private void SetFormatConfigValues(ref Formatter.FormatConfig config) { private void SetFormatConfigValues(ref Formatter.FormatConfig config) {
config.mSuppressImpliedAcc = true; config.mSuppressImpliedAcc = true;
config.mOperandWrapLen = 64;
config.mForceDirectOpcodeSuffix = "+1"; config.mForceDirectOpcodeSuffix = "+1";
config.mForceAbsOpcodeSuffix = "+2"; config.mForceAbsOpcodeSuffix = "+2";
config.mForceLongOpcodeSuffix = "+3"; config.mForceLongOpcodeSuffix = "+3";
@ -455,7 +455,7 @@ namespace SourceGen.AsmGen {
private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) { private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) {
Formatter formatter = SourceFormatter; Formatter formatter = SourceFormatter;
byte[] data = Project.FileData; byte[] data = Project.FileData;
int maxPerLine = MAX_OPERAND_LEN / formatter.CharsPerDenseByte; int maxPerLine = formatter.OperandWrapLen / formatter.CharsPerDenseByte;
string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense); string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense);
for (int i = 0; i < length; i += maxPerLine) { for (int i = 0; i < length; i += maxPerLine) {
@ -648,8 +648,7 @@ namespace SourceGen.AsmGen {
} }
StringOpFormatter stropf = new StringOpFormatter(SourceFormatter, StringOpFormatter stropf = new StringOpFormatter(SourceFormatter,
Formatter.DOUBLE_QUOTE_DELIM,StringOpFormatter.RawOutputStyle.CommaSep, Formatter.DOUBLE_QUOTE_DELIM,StringOpFormatter.RawOutputStyle.CommaSep, charConv);
MAX_OPERAND_LEN, charConv);
stropf.FeedBytes(data, offset, dfd.Length, leadingBytes, stropf.FeedBytes(data, offset, dfd.Length, leadingBytes,
StringOpFormatter.ReverseMode.Forward); StringOpFormatter.ReverseMode.Forward);

View File

@ -32,7 +32,6 @@ namespace SourceGen.AsmGen {
public class GenCc65 : IGenerator { public class GenCc65 : IGenerator {
private const string ASM_FILE_SUFFIX = "_cc65.S"; // must start with underscore private const string ASM_FILE_SUFFIX = "_cc65.S"; // must start with underscore
private const string CFG_FILE_SUFFIX = "_cc65.cfg"; // ditto private const string CFG_FILE_SUFFIX = "_cc65.cfg"; // ditto
private const int MAX_OPERAND_LEN = 64;
// IGenerator // IGenerator
public DisasmProject Project { get; private set; } public DisasmProject Project { get; private set; }
@ -181,6 +180,7 @@ namespace SourceGen.AsmGen {
/// Configures the assembler-specific format items. /// Configures the assembler-specific format items.
/// </summary> /// </summary>
private void SetFormatConfigValues(ref Formatter.FormatConfig config) { private void SetFormatConfigValues(ref Formatter.FormatConfig config) {
config.mOperandWrapLen = 64;
config.mForceDirectOpcodeSuffix = string.Empty; config.mForceDirectOpcodeSuffix = string.Empty;
config.mForceAbsOpcodeSuffix = string.Empty; config.mForceAbsOpcodeSuffix = string.Empty;
config.mForceLongOpcodeSuffix = string.Empty; config.mForceLongOpcodeSuffix = string.Empty;
@ -486,7 +486,7 @@ namespace SourceGen.AsmGen {
private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) { private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) {
Formatter formatter = SourceFormatter; Formatter formatter = SourceFormatter;
byte[] data = Project.FileData; byte[] data = Project.FileData;
int maxPerLine = MAX_OPERAND_LEN / formatter.CharsPerDenseByte; int maxPerLine = formatter.OperandWrapLen / formatter.CharsPerDenseByte;
string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense); string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense);
for (int i = 0; i < length; i += maxPerLine) { for (int i = 0; i < length; i += maxPerLine) {
@ -709,8 +709,7 @@ namespace SourceGen.AsmGen {
} }
StringOpFormatter stropf = new StringOpFormatter(SourceFormatter, StringOpFormatter stropf = new StringOpFormatter(SourceFormatter,
Formatter.DOUBLE_QUOTE_DELIM, StringOpFormatter.RawOutputStyle.CommaSep, Formatter.DOUBLE_QUOTE_DELIM, StringOpFormatter.RawOutputStyle.CommaSep, charConv);
MAX_OPERAND_LEN, charConv);
stropf.FeedBytes(data, offset, dfd.Length - trailingBytes, leadingBytes, stropf.FeedBytes(data, offset, dfd.Length - trailingBytes, leadingBytes,
StringOpFormatter.ReverseMode.Forward); StringOpFormatter.ReverseMode.Forward);

View File

@ -32,7 +32,6 @@ namespace SourceGen.AsmGen {
/// </summary> /// </summary>
public class GenMerlin32 : IGenerator { public class GenMerlin32 : IGenerator {
private const string ASM_FILE_SUFFIX = "_Merlin32.S"; // must start with underscore private const string ASM_FILE_SUFFIX = "_Merlin32.S"; // must start with underscore
private const int MAX_OPERAND_LEN = 64;
// IGenerator // IGenerator
public DisasmProject Project { get; private set; } public DisasmProject Project { get; private set; }
@ -155,6 +154,7 @@ namespace SourceGen.AsmGen {
/// Configures the assembler-specific format items. /// Configures the assembler-specific format items.
/// </summary> /// </summary>
private void SetFormatConfigValues(ref Formatter.FormatConfig config) { private void SetFormatConfigValues(ref Formatter.FormatConfig config) {
config.mOperandWrapLen = 64;
config.mForceDirectOpcodeSuffix = string.Empty; config.mForceDirectOpcodeSuffix = string.Empty;
config.mForceAbsOpcodeSuffix = ":"; config.mForceAbsOpcodeSuffix = ":";
config.mForceLongOpcodeSuffix = "l"; config.mForceLongOpcodeSuffix = "l";
@ -333,7 +333,7 @@ namespace SourceGen.AsmGen {
private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) { private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) {
Formatter formatter = SourceFormatter; Formatter formatter = SourceFormatter;
byte[] data = Project.FileData; byte[] data = Project.FileData;
int maxPerLine = MAX_OPERAND_LEN / formatter.CharsPerDenseByte; int maxPerLine = formatter.OperandWrapLen / formatter.CharsPerDenseByte;
string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense); string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense);
for (int i = 0; i < length; i += maxPerLine) { for (int i = 0; i < length; i += maxPerLine) {
@ -607,7 +607,7 @@ namespace SourceGen.AsmGen {
StringOpFormatter stropf = new StringOpFormatter(SourceFormatter, StringOpFormatter stropf = new StringOpFormatter(SourceFormatter,
new Formatter.DelimiterDef(delim), new Formatter.DelimiterDef(delim),
StringOpFormatter.RawOutputStyle.DenseHex, MAX_OPERAND_LEN, charConv); StringOpFormatter.RawOutputStyle.DenseHex, charConv);
if (dfd.FormatType == FormatDescriptor.Type.StringDci) { if (dfd.FormatType == FormatDescriptor.Type.StringDci) {
// DCI is awkward because the character encoding flips on the last byte. Rather // 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 // than clutter up StringOpFormatter for this rare item, we just accept low/high

View File

@ -45,7 +45,6 @@ namespace SourceGen.AsmGen {
private const string ASM_FILE_SUFFIX = "_64tass.S"; // must start with underscore private const string ASM_FILE_SUFFIX = "_64tass.S"; // must start with underscore
private const string ASCII_ENC_NAME = "sg_ascii"; private const string ASCII_ENC_NAME = "sg_ascii";
private const string HIGH_ASCII_ENC_NAME = "sg_hiascii"; private const string HIGH_ASCII_ENC_NAME = "sg_hiascii";
private const int MAX_OPERAND_LEN = 64;
// IGenerator // IGenerator
public DisasmProject Project { get; private set; } public DisasmProject Project { get; private set; }
@ -188,6 +187,7 @@ namespace SourceGen.AsmGen {
config.mUpperOperandA = false; config.mUpperOperandA = false;
config.mUpperOperandS = false; config.mUpperOperandS = false;
config.mUpperOperandXY = false; config.mUpperOperandXY = false;
config.mOperandWrapLen = 64;
config.mBankSelectBackQuote = true; config.mBankSelectBackQuote = true;
@ -524,7 +524,7 @@ namespace SourceGen.AsmGen {
private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) { private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) {
Formatter formatter = SourceFormatter; Formatter formatter = SourceFormatter;
byte[] data = Project.FileData; byte[] data = Project.FileData;
int maxPerLine = MAX_OPERAND_LEN / formatter.CharsPerDenseByte; int maxPerLine = formatter.OperandWrapLen / formatter.CharsPerDenseByte;
string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense); string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense);
for (int i = 0; i < length; i += maxPerLine) { for (int i = 0; i < length; i += maxPerLine) {
@ -744,8 +744,7 @@ namespace SourceGen.AsmGen {
} }
StringOpFormatter stropf = new StringOpFormatter(SourceFormatter, StringOpFormatter stropf = new StringOpFormatter(SourceFormatter,
Formatter.DOUBLE_QUOTE_DELIM,StringOpFormatter.RawOutputStyle.CommaSep, Formatter.DOUBLE_QUOTE_DELIM,StringOpFormatter.RawOutputStyle.CommaSep, charConv);
MAX_OPERAND_LEN, charConv);
if (dfd.FormatType == FormatDescriptor.Type.StringDci) { if (dfd.FormatType == FormatDescriptor.Type.StringDci) {
// DCI is awkward because the character encoding flips on the last byte. Rather // 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 // than clutter up StringOpFormatter for this rare item, we just accept low/high

View File

@ -425,6 +425,8 @@ namespace SourceGen.AsmGen {
settings.GetBool(AppSettings.FMT_SPACES_BETWEEN_BYTES, false); settings.GetBool(AppSettings.FMT_SPACES_BETWEEN_BYTES, false);
config.mAddSpaceLongComment = config.mAddSpaceLongComment =
settings.GetBool(AppSettings.FMT_ADD_SPACE_FULL_COMMENT, true); settings.GetBool(AppSettings.FMT_ADD_SPACE_FULL_COMMENT, true);
config.mOperandWrapLen =
settings.GetInt(AppSettings.FMT_OPERAND_WRAP_LEN, 0);
config.mForceAbsOpcodeSuffix = config.mForceAbsOpcodeSuffix =
settings.GetString(AppSettings.FMT_OPCODE_SUFFIX_ABS, string.Empty); settings.GetString(AppSettings.FMT_OPCODE_SUFFIX_ABS, string.Empty);

View File

@ -33,8 +33,6 @@ namespace SourceGen {
/// multiple lines. /// multiple lines.
/// </summary> /// </summary>
public class PseudoOp { public class PseudoOp {
private const int MAX_OPERAND_LEN = 64;
/// <summary> /// <summary>
/// One piece of the pseudo-instruction. /// One piece of the pseudo-instruction.
/// </summary> /// </summary>
@ -278,7 +276,7 @@ namespace SourceGen {
return 1; return 1;
case FormatDescriptor.Type.Dense: { case FormatDescriptor.Type.Dense: {
// no delimiter, two output bytes per input byte // no delimiter, two output bytes per input byte
int maxLen = MAX_OPERAND_LEN; int maxLen = formatter.OperandWrapLen;
int textLen = dfd.Length * formatter.CharsPerDenseByte; int textLen = dfd.Length * formatter.CharsPerDenseByte;
return (textLen + maxLen - 1) / maxLen; return (textLen + maxLen - 1) / maxLen;
} }
@ -367,7 +365,7 @@ namespace SourceGen {
} }
break; break;
case FormatDescriptor.Type.Dense: { case FormatDescriptor.Type.Dense: {
int maxPerLine = MAX_OPERAND_LEN / formatter.CharsPerDenseByte; int maxPerLine = formatter.OperandWrapLen / formatter.CharsPerDenseByte;
offset += subIndex * maxPerLine; offset += subIndex * maxPerLine;
length -= subIndex * maxPerLine; length -= subIndex * maxPerLine;
if (length > maxPerLine) { if (length > maxPerLine) {
@ -547,7 +545,7 @@ namespace SourceGen {
} }
StringOpFormatter stropf = new StringOpFormatter(formatter, delDef, StringOpFormatter stropf = new StringOpFormatter(formatter, delDef,
StringOpFormatter.RawOutputStyle.CommaSep, MAX_OPERAND_LEN, charConv); StringOpFormatter.RawOutputStyle.CommaSep, charConv);
stropf.FeedBytes(data, offset + hiddenLeadingBytes, stropf.FeedBytes(data, offset + hiddenLeadingBytes,
dfd.Length - hiddenLeadingBytes - trailingBytes, 0, revMode); dfd.Length - hiddenLeadingBytes - trailingBytes, 0, revMode);

View File

@ -100,6 +100,65 @@ do not affect generated code, which must use the delimiter characters
specified by the chosen assembler.</p> 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> <h3><a name="appset-asmconfig">Asm Config</a></h3>
<p>These settings configure cross-assemblers and modify assembly source <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> 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> <h2><a name="project-properties">Project Properties</a></h2>
<p>Project properties are stored in the .dis65 project file. <p>Project properties are stored in the .dis65 project file.

View File

@ -389,6 +389,7 @@ namespace SourceGen.Tests {
settings.SetBool(AppSettings.FMT_UPPER_OPERAND_S, true); settings.SetBool(AppSettings.FMT_UPPER_OPERAND_S, true);
settings.SetBool(AppSettings.FMT_UPPER_OPERAND_XY, false); settings.SetBool(AppSettings.FMT_UPPER_OPERAND_XY, false);
settings.SetBool(AppSettings.FMT_ADD_SPACE_FULL_COMMENT, 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 // 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 // mandatory, since the generated code is only guaranteed to work with the

View File

@ -129,10 +129,10 @@ limitations under the License.
<GroupBox Grid.Column="2" Grid.Row="1" Header="Miscellaneous" <GroupBox Grid.Column="2" Grid.Row="1" Header="Miscellaneous"
Margin="10,0,0,0" Padding="2,4"> Margin="10,0,0,0" Padding="2,4">
<StackPanel> <StackPanel>
<CheckBox Content="Add spaces in bytes column" Margin="0,4"
IsChecked="{Binding SpacesBetweenBytes}"/>
<CheckBox Content="Use &quot;dark&quot; color scheme" Margin="0,4" <CheckBox Content="Use &quot;dark&quot; color scheme" Margin="0,4"
IsChecked="{Binding DarkColorScheme}"/> IsChecked="{Binding DarkColorScheme}"/>
<CheckBox Content="Add spaces in bytes column" Margin="0,4"
IsChecked="{Binding SpacesBetweenBytes}"/>
</StackPanel> </StackPanel>
</GroupBox> </GroupBox>
@ -422,180 +422,120 @@ limitations under the License.
</TabItem> </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>
<TabItem Name="displayFormatTab" Header="Display Format"> <TabItem Name="displayFormatTab" Header="Display Format">
<DockPanel LastChildFill="False"> <Grid>
<TextBlock DockPanel.Dock="Top" Margin="4,0,0,0" <Grid.ColumnDefinitions>
Text="Configure display format options. This does not affect source code generation."/> <ColumnDefinition Width="*"/>
<GroupBox Header="Operand Width Disambiguator" Width="300" DockPanel.Dock="Top" <ColumnDefinition Width="Auto"/>
HorizontalAlignment="Left" Margin="0,8,0,0" Padding="2,0"> <ColumnDefinition Width="*"/>
<Grid> </Grid.ColumnDefinitions>
<Grid.ColumnDefinitions> <Grid.RowDefinitions>
<ColumnDefinition Width="*"/> <RowDefinition Height="Auto"/>
<ColumnDefinition Width="*"/> <RowDefinition Height="*"/>
<ColumnDefinition Width="20"/> </Grid.RowDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" <TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Margin="4,0,0,0"
Text="Opcode suffix:" Margin="0,4,0,0"/> Text="Configure opcode/operand display format options. This does not affect source code generation."/>
<TextBlock Grid.Column="3" Grid.Row="0" Grid.ColumnSpan="2" <DockPanel Grid.Column="0" Grid.Row="1" LastChildFill="False">
Text="Operand prefix:" Margin="0,4,0,0"/> <GroupBox Header="Operand Width Disambiguator" Width="300" DockPanel.Dock="Top"
HorizontalAlignment="Left" Margin="0,8,0,0" Padding="2,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="1" Text="16-bit:" <TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"
Margin="0,4,0,0"/> Text="Opcode suffix:" Margin="0,4,0,0"/>
<TextBox Grid.Column="1" Grid.Row="1" Margin="0,4,0,0" MaxLength="8" <TextBlock Grid.Column="3" Grid.Row="0" Grid.ColumnSpan="2"
FontFamily="{StaticResource GeneralMonoFont}" Text="Operand prefix:" Margin="0,4,0,0"/>
Text="{Binding OpcodeSuffixAbs, UpdateSourceTrigger=PropertyChanged,
FallbackValue=.placeho}"/>
<TextBlock Grid.Column="3" Grid.Row="1" Text="16-bit:"
Margin="0,4,0,0"/>
<TextBox Grid.Column="4" Grid.Row="1" Margin="0,4,0,0" MaxLength="8"
FontFamily="{StaticResource GeneralMonoFont}"
Text="{Binding OperandPrefixAbs, UpdateSourceTrigger=PropertyChanged,
FallbackValue=.placeho}"/>
<TextBlock Grid.Column="0" Grid.Row="2" Text="24-bit:" <TextBlock Grid.Column="0" Grid.Row="1" Text="16-bit:"
Margin="0,4,0,0"/> Margin="0,4,0,0"/>
<TextBox Grid.Column="1" Grid.Row="2" Margin="0,4,0,0" MaxLength="8" <TextBox Grid.Column="1" Grid.Row="1" Margin="0,4,0,0" MaxLength="8"
FontFamily="{StaticResource GeneralMonoFont}" FontFamily="{StaticResource GeneralMonoFont}"
Text="{Binding OpcodeSuffixLong, UpdateSourceTrigger=PropertyChanged, Text="{Binding OpcodeSuffixAbs, UpdateSourceTrigger=PropertyChanged,
FallbackValue=.placeho}"/> FallbackValue=.placeho}"/>
<TextBlock Grid.Column="3" Grid.Row="2" Text="24-bit:" <TextBlock Grid.Column="3" Grid.Row="1" Text="16-bit:"
Margin="0,4,0,0"/> Margin="0,4,0,0"/>
<TextBox Grid.Column="4" Grid.Row="2" Margin="0,4,0,0" MaxLength="8" <TextBox Grid.Column="4" Grid.Row="1" Margin="0,4,0,0" MaxLength="8"
FontFamily="{StaticResource GeneralMonoFont}" FontFamily="{StaticResource GeneralMonoFont}"
Text="{Binding OperandPrefixLong, UpdateSourceTrigger=PropertyChanged, Text="{Binding OperandPrefixAbs, UpdateSourceTrigger=PropertyChanged,
FallbackValue=.placeho}"/> FallbackValue=.placeho}"/>
</Grid>
</GroupBox>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="4,16,0,0"> <TextBlock Grid.Column="0" Grid.Row="2" Text="24-bit:"
<TextBlock Text="Expression style:" Margin="0,3,0,0"/> Margin="0,4,0,0"/>
<ComboBox Name="expressionStyleComboBox" Width="120" Margin="8,0,0,0" <TextBox Grid.Column="1" Grid.Row="2" Margin="0,4,0,0" MaxLength="8"
ItemsSource="{Binding ExpressionStyleItems}" DisplayMemberPath="Name" FontFamily="{StaticResource GeneralMonoFont}"
IsReadOnly="True" Text="{Binding OpcodeSuffixLong, UpdateSourceTrigger=PropertyChanged,
SelectionChanged="ExpressionStyleComboBox_SelectionChanged"/> FallbackValue=.placeho}"/>
</StackPanel> <TextBlock Grid.Column="3" Grid.Row="2" Text="24-bit:"
Margin="0,4,0,0"/>
<TextBox Grid.Column="4" Grid.Row="2" Margin="0,4,0,0" MaxLength="8"
FontFamily="{StaticResource GeneralMonoFont}"
Text="{Binding OperandPrefixLong, UpdateSourceTrigger=PropertyChanged,
FallbackValue=.placeho}"/>
</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="Non-unique label prefix:"/> <TextBlock Text="Expression style:" Margin="0,3,0,0"/>
<TextBox Width="14" MaxLength="1" Margin="8,1,0,0" <ComboBox Name="expressionStyleComboBox" Width="120" Margin="8,0,0,0"
Text="{Binding NonUniqueLabelPrefix, UpdateSourceTrigger=PropertyChanged, ItemsSource="{Binding ExpressionStyleItems}" DisplayMemberPath="Name"
FallbackValue=@}" IsReadOnly="True"
FontFamily="{StaticResource GeneralMonoFont}"/> SelectionChanged="ExpressionStyleComboBox_SelectionChanged"/>
</StackPanel> </StackPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="4,4,0,0"> <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="4,8,0,0">
<TextBlock Text="Local variable prefix:"/> <TextBlock Text="Non-unique label prefix:"/>
<TextBox Width="66" MaxLength="8" Margin="8,1,0,0" <TextBox Width="14" MaxLength="1" Margin="8,1,0,0"
Text="{Binding LocalVarPrefix, UpdateSourceTrigger=PropertyChanged, Text="{Binding NonUniqueLabelPrefix, UpdateSourceTrigger=PropertyChanged,
FallbackValue=.placeho}" FallbackValue=@}"
FontFamily="{StaticResource GeneralMonoFont}"/> FontFamily="{StaticResource GeneralMonoFont}"/>
</StackPanel> </StackPanel>
<CheckBox DockPanel.Dock="Top" Margin="4,6,0,0" <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="4,4,0,0">
Content="Use comma-separated format for bulk data" <TextBlock Text="Local variable prefix:"/>
IsChecked="{Binding CommaSeparatedBulkData}"/> <TextBox Width="66" MaxLength="8" Margin="8,1,0,0"
Text="{Binding LocalVarPrefix, UpdateSourceTrigger=PropertyChanged,
FallbackValue=.placeho}"
FontFamily="{StaticResource GeneralMonoFont}"/>
</StackPanel>
<GroupBox DockPanel.Dock="Bottom" Header="Quick Set" <GroupBox DockPanel.Dock="Bottom" Header="Quick Set"
HorizontalAlignment="Right" Padding="2,4"> HorizontalAlignment="Left" Padding="2,4">
<ComboBox Name="displayFmtQuickComboBox" DockPanel.Dock="Right" <ComboBox Name="displayFmtQuickComboBox" DockPanel.Dock="Right"
Width="170" IsReadOnly="True" Width="170" IsReadOnly="True"
ItemsSource="{Binding DisplayPresets}" DisplayMemberPath="Name" ItemsSource="{Binding DisplayPresets}" DisplayMemberPath="Name"
SelectionChanged="DisplayFmtQuickComboBox_SelectionChanged"/> SelectionChanged="DisplayFmtQuickComboBox_SelectionChanged"/>
</GroupBox> </GroupBox>
</DockPanel> </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> </TabItem>
@ -775,6 +715,92 @@ limitations under the License.
</GroupBox> </GroupBox>
</DockPanel> </DockPanel>
</TabItem> </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> </TabControl>
</DockPanel> </DockPanel>
</Window> </Window>

View File

@ -74,9 +74,9 @@ namespace SourceGen.WpfGui {
Unknown = 0, Unknown = 0,
CodeView, CodeView,
TextDelimiters, TextDelimiters,
AsmConfig,
DisplayFormat, DisplayFormat,
PseudoOp PseudoOp,
AsmConfig
} }
/// <summary> /// <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 class DisplayFormatPreset {
public const int ID_CUSTOM = -2; public const int ID_CUSTOM = -2;
public const int ID_DEFAULT = -1; public const int ID_DEFAULT = -1;
@ -1024,6 +1043,9 @@ namespace SourceGen.WpfGui {
} }
SelectExpressionStyle(mode); SelectExpressionStyle(mode);
int wrapLen = mSettings.GetInt(AppSettings.FMT_OPERAND_WRAP_LEN, 0);
SelectOperandWrapLen(wrapLen);
// No need to set this to anything specific. // No need to set this to anything specific.
UpdateDisplayFormatQuickCombo(); UpdateDisplayFormatQuickCombo();
} }
@ -1038,10 +1060,30 @@ namespace SourceGen.WpfGui {
return; return;
} }
} }
Debug.Assert(false, "Expression mode " + mode + " not found"); Debug.Assert(false, "Expression mode " + mode + " not found in combo box");
expressionStyleComboBox.SelectedIndex = 0; 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> /// <summary>
/// Handles a change to the expression style. /// Handles a change to the expression style.
/// </summary> /// </summary>
@ -1110,6 +1152,13 @@ namespace SourceGen.WpfGui {
mSettingDisplayFmtCombo = false; 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 #endregion Display Format
#region PseudoOp #region PseudoOp