1
0
mirror of https://github.com/fadden/6502bench.git synced 2024-06-24 08:29:29 +00:00

Instruction operand editor rework, part 4 (of 4)

Updated the manual, and changed tutorial #2 to use local variables
for pointers.

If the symbol text box isn't empty, use the string as the initial
value for the Label when creating a new project property.

Fixed a crash when editing a project property.
This commit is contained in:
Andy McFadden 2019-09-08 21:56:47 -07:00
parent 4d9d5e2ecf
commit bb23bf82d1
7 changed files with 144 additions and 81 deletions

View File

@ -1892,11 +1892,14 @@ namespace SourceGen {
// Check for changes to a project property. The dialog can create a new entry or
// modify an existing entry.
if (dlg.ProjectPropertyResult != null) {
DefSymbol defSym = dlg.ProjectPropertyResult;
DefSymbol oldSym = dlg.PrevProjectPropertyResult;
DefSymbol newSym = dlg.ProjectPropertyResult;
ProjectProperties newProps = new ProjectProperties(mProject.ProjectProps);
// Add new entry, or replace existing entry.
newProps.ProjectSyms.Remove(dlg.PrevProjectPropertyResult.Label);
newProps.ProjectSyms.Add(defSym.Label, defSym);
if (oldSym != null) {
newProps.ProjectSyms.Remove(oldSym.Label);
}
newProps.ProjectSyms.Add(newSym.Label, newSym);
UndoableChange uc = UndoableChange.CreateProjectPropertiesChange(
mProject.ProjectProps, newProps);
cs.Add(uc);

View File

@ -51,45 +51,81 @@ be imported by other projects (see
<a href="advanced.html#multi-bin">Working With Multiple Binaries</a>).</p>
<h2><a name="operand">Edit Instruction Operand</a></h2>
<h2><a name="instruction-operand">Edit Instruction Operand</a></h2>
<p>Operands can be formatted explicitly, or you can let the disassembler
select the format for you. By default, immediate constants and
addresses with no matching symbol are formatted as hex. Symbols
defined as address labels, platform/project symbols, and local
variables will be identified and applied automatically.</p>
<h3><a name="explicit-format">Explicit Formats</a></h3>
<p>Operands can be displayed in a variety of numeric formats, or as a
symbol. The character formats are only available for operands
whose value falls into the proper range. The ASCII format handles
both plain and high ASCII; the correct encoding is chosen based on
the character data.</p>
<p>Symbols may be used in their entirety, or shifted and masked.
the operand's value.</p>
<p>Symbols may be used in their entirety, or, when used as constants,
can be shifted and masked.
The low / high / bank selector determines which byte is used as the
low byte. For 16-bit operands, this acts as a shift rather than a byte
select. If the symbol is wider than the operand field, a mask will be
select. If the symbol is wider than the operand field, e.g. you're
referencing a 16-bit address in an 8-bit constant, a mask will be
applied automatically.</p>
<p>A few shortcuts are provided when specifying a symbol. As noted in
the introductory sections, operand symbols are weak references. If the
symbol hasn't been defined as a label yet, the operand will be formatted
as hex, which is probably not what you want.</p>
<p>The default behavior is just to set the operand's symbol.</p>
<p>For operands that target an offset inside the file, if the target
address does not yet have a label, and the symbol doesn't exist, you may
set the symbol as the label on the target address as well. You can do
this in addition to setting the operand symbol, or in lieu of setting the
operand symbol. (You will often want to only create the label, and let
SourceGen convert the numeric reference to a symbolic reference
automatically.) If you select the "set label instead" option, and the
operand already had a symbol reference defined, the operand's format will
be set to default.</p>
<p>For operands that target an external address, if the symbol doesn't
exist, you can ask the editor to create a project symbol with the
appropriate label and address value. The operand symbol will also be set.</p>
<p>The editor will try to prevent you from using auto-generated
labels and local variables in the symbol field. These types of symbols
can be freely renamed by SourceGen, and thus cannot be reliably
referenced by name.</p>
<p>When you select a non-default format option, a "preview" of the
formatted operand will be shown.</p>
<p>The <code>MVN</code> and <code>MVP</code> instructions on the 65816
are a bit peculiar, because they have two operands rather than one.
SourceGen currently only allows you to set one format, which will be
applied to both operands. If you specify a symbol, the symbol will
be used twice, adjusted if necessary. (This may be addressed in a
future release.)</p>
be used twice, adjusted if necessary. (This limitation may be addressed
in a future release.)</p>
<p>The bottom part of the window has some shortcuts for working with
address references and local variables. These are primarily used to
change the way things work when "Default" is selected. The shortcuts
don't cause any changes to the recorded format of the instruction
being edited. All of the actions can be performed elsewhere, by
editing the label at the target address, editing the project symbol
set, or editing a local variable table.</p>
<h3><a name="shortcut-nar">Numeric Address References</a></h3>
<p>For operands that are 8-bit, 16-bit, or 24-bit addresses, you can
define a symbol for the address as a label or project symbol.</p>
<p>If the operand is an address inside the project, you can set a
label at that address. If the address falls in the middle of an
instruction or multi-byte data item, its position will be adjusted to
the start. Labels may be created, modified, or (by erasing the label)
deleted.</p>
<p>The label finder does not do the optional search for "nearby" labels
that the main analyzer does, so there will be times when an instruction
that is shown with a symbol in the code list won't have a label
in the editor.</p>
<p>If the operand is an address outside the project, e.g. a ROM
address or frame buffer, you can define a project symbol. If a
match was found in the configured platform definition files, it will be
shown; it can't be edited, but it can be overridden by a project symbol.
You can create or modify a project symbol, but you can't delete one
from this editor (use Project Properties instead). If more than one
project symbol has the same address, the first one found will be used.</p>
<h3><a name="shortcut-local-var">Local Variable References</a></h3>
<p>For zero-page address operands and (65816-only) stack-relative
constant operands, a local variable can be created or modified. This
requires that a local variable table has been defined at or before
the instruction being edited.</p>
<p>If an existing entry is found, you will be able to edit the name
and comment fields. If not, a new entry with a generic name and
pre-filled value field will be created in the nearest table.</p>
<h2><a name="data">Edit Data Operand</a></h2>
<h2><a name="data-operand">Edit Data Operand</a></h2>
<p>This dialog offers a variety of choices, and can be used to apply a
format to multiple lines. You must select all of the bytes you want
to format. For example, to format two bytes as a 16-bit word, you must

View File

@ -71,8 +71,13 @@ and 65816 code. The official web site is
<li><a href="editors.html#address">Edit Address</a></li>
<li><a href="editors.html#flags">Edit Status Flags</a></li>
<li><a href="editors.html#label">Edit Label</a></li>
<li><a href="editors.html#operand">Edit Instruction Operand</a></li>
<li><a href="editors.html#data">Edit Data Operand</a></li>
<li><a href="editors.html#instruction-operand">Edit Instruction Operand</a>
<ul>
<li><a href="editors.html#explicit-format">Explicit Formats</a></li>
<li><a href="editors.html#shortcut-nar">Numeric Address References</a></li>
<li><a href="editors.html#shortcut-local-var">Local Variable References</a></li>
</ul></li>
<li><a href="editors.html#data-operand">Edit Data Operand</a></li>
<li><a href="editors.html#comment">Edit Comment</a></li>
<li><a href="editors.html#long-comment">Edit Long Comment</a></li>
<li><a href="editors.html#note">Edit Note</a></li>

View File

@ -131,8 +131,8 @@ assembler directive.</p>
<li><b>Operand</b>. The instruction or data operand. Data operands
may span a large number of bytes. Double-click on this field to
open the
<a href="editors.html#operand">Edit Operand</a> or
<a href="editors.html#data">Edit Data Format</a> dialog, as
<a href="editors.html#instruction-operand">Edit Instruction Operand</a>
or <a href="editors.html#data-operand">Edit Data Operand</a> dialog, as
appropriate. (Note you can shift-double-click on data items to
edit multiple lines.)</li>
<li><b>Comment</b>. End-of-line comment, generally shown with a ';'
@ -168,8 +168,8 @@ enabled will depend on what you have selected in the main window.</p>
<li><a href="editors.html#label">Edit Label</a>. Sets the label
at that offset. Enabled when a single instruction or data line is
selected.</li>
<li><a href="editors.html#operand">Edit Operand</a>. Opens the
Edit Instruction Operand or Edit Data Format window, depending on
<li><a href="editors.html#instruction-operand">Edit Operand</a>. Opens the
Edit Instruction Operand or Edit Data Operand window, depending on
what's selected.
Enabled when a single instruction line is selected, or when one
or more data lines are selected.</li>
@ -451,7 +451,7 @@ undoable action, so if it comes out looking wrong, just hit "undo".</p>
<p>The "Toggle Single-Byte Format" feature provides a quick way to
change a range of bytes to single bytes
or back to their default format. It's equivalent to opening the Edit
Data Format dialog and selecting "Single bytes" displayed as hex, or
Data Operand dialog and selecting "Single bytes" displayed as hex, or
selecting "Default".</p>
<p>This can be handy if the default format for a range of bytes is a
string, but you want to see it as bytes or set a label in the middle.</p>
@ -460,7 +460,7 @@ string, but you want to see it as bytes or set a label in the middle.</p>
<h3><a name="format-as-word">Format As Word</a></h3>
<p>This is a quick way to format pairs of bytes as 16-bit words. It's
equivalent to opening the Edit Data Format dialog and selecting
equivalent to opening the Edit Data Operand dialog and selecting
"16-bit words, little-endian", displayed as hex.</p>
<p>To avoid some confusing situations, it only works on sets of
@ -472,7 +472,7 @@ can turn off auto-generation of strings and .FILLs with
<p>As a special case, if you select a single byte, the following byte will
also be selected. This won't work if the following byte is part of a
multi-byte data item, is the start of a new region (see
<a href="editors.html#data">Edit Data Format</a> for a definition of
<a href="editors.html#data-operand">Edit Data Operand</a> for a definition of
what splits a region), or is the last byte in the file.</p>

View File

@ -45,7 +45,7 @@ open the Examples folder, then open the "Tutorial" folder. Select the
file named "Tutorial1", and click "Open".</p>
<p>The filename now appears in the bottom window, along with an indication
of the file's size.</p>
<p>Click OK to create the project.</p>
<p>Click "OK" to create the project.</p>
<h3>Getting Around</h3>
@ -142,7 +142,7 @@ convenient way to edit something: point and click.</p>
upper window, and note that a formatted version appears in the bottom
window. Experiment with the maximum line width and "render in box"
settings to see what they do. You can hit Enter to create line breaks,
or let SourceGen wrap lines for you. When you're done, click OK. (Or
or let SourceGen wrap lines for you. When you're done, click "OK". (Or
hit Ctrl+Enter.)</p>
<p>When the dialog closes, you'll see your new comment in place at the
top of the file. If you typed enough words, your comment will span
@ -206,8 +206,9 @@ or double-click on "$3000". Select the "Symbol" radio button, then type
"INPUT" in the text box. Click "OK".</p>
<p>Disappointed? Nothing seems to have happened. The problem is that we
updated the operand to reference a symbol that doesn't exist. Open the
operand editor again, but this time click on "Set operand AND create project
symbol". Click "OK".</p>
operand editor again, but this time click on "Create Project Symbol" at
the bottom left. Enter "INPUT" in the Label field, and click "OK", then
click "OK" in the operand editor.</p>
<p>That's better. If you scroll up to the top of the project, you'll see
that there's now a ".EQ" line for the symbol.</p>
<p>Operands that refer to in-file locations behave similarly. Select the
@ -228,18 +229,17 @@ as a hexadecimal value.</p>
Actions &gt; Edit Label. Enter "IS_OK", and hit Enter. (NOTE: labels are
case-sensitive, so it needs to match the operand at $2005 exactly.) You'll
see the new label appear, and the operand at line $2005 will use it.</p>
<p>There's an easier way. Use Edit &gt; Undo twice, to get back to the time
where line $2005 is using "L2009" as its operand. Select that line and
Actions &gt; Edit Operand. Enter "IS_OK", then select "Create label at target
address instead". Hit "OK".</p>
<p>There's an easier way. Double-click on the "BCC" opcode at address
$2005. This moves the selection to $2009. Double-click on the label field,
and enter "IS_OK". Hit "OK".</p>
<p>You should now see that both the operand at $2005 and the label at
$2009 have changed to IS_OK, accomplishing what we wanted to do in a
single step. (There's actually a subtle difference compared to the two-step
process: the operand at $2005 is still a numeric reference. It was
automatically changed to match IS_OK in the same way that the references
to MAIN were when we renamed "L2000" earlier. If you actually do want the
symbolic reference, there's another option in the Edit Operand dialog that
does it. The difference can be noted in the Info window.)</p>
single step. The key difference is that we haven't explicitly set a
format for the BCC operand -- we just defined a label, and SourceGen
used it automatically.</p>
<p>We could do the exact same thing by using Edit Operand on
the BCC line, clicking the "Create Label" button, and typing "IS_OK".
Sometimes one approach is more convenient than the other.</p>
<h3>Editing Data Operands</h3>
@ -264,7 +264,8 @@ label to "STR1". Move up a bit and select address $2030, then scroll to
the bottom and shift-click address $2070. Select Actions &gt; Edit Operand.
At the top it should now say, "65 bytes selected in 2 groups".
There are two groups because the presence of a label split the data into
two separate regions. Select "Low or High ASCII" encoding, select the
two separate regions. From the "Character encoding" pop-up select
"Low or High ASCII" encoding, select the
"mixed character and non-character" string type, then click "OK".</p>
<p>We now have two ".STR" lines, one for "string zero ", and one with the
STR1 label and the rest of the string data. This is okay, but it's not
@ -336,14 +337,14 @@ can do. We assume you've already finished the Basic Features tutorial.</p>
<p>Start a new project. Select the Apple //e platform, click Select File
and navigate to the Examples directory. In A2-Amper-fdraw, select
<code>AMPERFDRAW#061d60</code>. Click OK to create the project.</p>
<code>AMPERFDRAW#061d60</code>. Click "OK" to create the project.</p>
<p>Not a lot to see here -- just half a dozen lines of loads and stores.
This particular program interfaces with Applesoft BASIC, so we can make it
a bit more meaningful by loading an additional platform
symbol file. Select Edit &gt; Project Properties, then the Symbol Files
tab. Click Add Symbol Files. The file browser starts in the RuntimeData
directory. In the Apple folder, select <code>Applesoft.sym65</code>, and
click Open. Click OK to close the project properties window.</p>
click Open. Click "OK" to close the project properties window.</p>
<p>The STA instructions now reference <code>AMPERV</code>, which is noted
as a call vector. We can see the code setting up a jump (opcode $4c) to
$1d70. As it happens, the start address of the code is $1d60 -- the last
@ -370,7 +371,7 @@ up a bit. Set a label on the code at $1db5 called "FUNC". At $1d97, edit
the data item (double-click on "$b4"), click "Single bytes", then type "FUNC"
(note the text field gets focus immediately, and the radio button
automatically switches to "symbolic reference" when you start typing).
Click OK. The operand at $1d97 should now say <code>&lt;FUNC-1</code>.
Click "OK". The operand at $1d97 should now say <code>&lt;FUNC-1</code>.
Repeat the process at $1da6, this time clicking the "High" part radio button
below the symbol entry text box,
to make the operand there say <code>&gt;FUNC</code>. (If it says
@ -390,7 +391,7 @@ that location, so a label will be generated automatically.</p>
<p>Down near the bottom, check the "add code entry hint if needed" checkbox.
Because we saw the table contents being pushed onto the stack for RTS,
we know that they're all code entry points.</p>
<p>Click OK. The table of address bytes at $1d97 should now all be
<p>Click "OK". The table of address bytes at $1d97 should now all be
references to symbols -- 15 low parts followed by 15 high parts. If you
scroll down, you should see nothing but instructions until you get to the
last dozen bytes at the end of the file. (If this isn't the case, use
@ -439,15 +440,16 @@ it official. But first, let's do it wrong. Click on the line with
address $2004 to select it. Hold the shift key down, then double-click
on the operand field of the line with address $2031 (i.e. double-click on
the words "last string").</p>
<p>The Edit Data Format dialog opens, but the null-terminated strings
<p>The Edit Data Operand dialog opens, but the null-terminated strings
option is not available. This is because we didn't include the null byte
on the last string. To be recognized as one of the "special" string types,
every selected string must match the expected pattern.</p>
<p>Cancel out of the dialog. Hold the shift key down, and double-click
on the operand on line $203c (<code>$00</code>).
You should see "Null-terminated strings (4)" as an available
option now. Click on that, then click OK. The strings are now shown
as .ZSTR operands.</p>
option now (make sure the Character Encoding pop-up is set to
"Low or High ASCII"). Click on that, then click "OK". The strings are now
shown as .ZSTR operands.</p>
<p>It's wise to save your work periodically. Use File &gt; Save to create
a project file for Tutorial2.</p>
@ -460,16 +462,20 @@ pointer to $2063, which is a data area inside the file. So let's make it
official.</p>
<p>Select the line at address $2063, and use Actions &gt; Edit Label to
give it the label "XDATA". Now edit the operand on line $203d, and set it
to the symbol "XDATA", with the part "low". Edit the operand on line $2043,
to the symbol "XDATA", with the part "low". Edit the operand on line $2041,
and set it to "XDATA" with the part "high". (Note the symbol text box
gets focus immediately, so you can start typing the symbol name as soon
as the dialog opens; you don't need to click around first.) If all
went well, the operands should now read <code>LDA #&lt;XDATA</code>
and <code>LDA #&gt;XDATA</code>.</p>
<p>Let's name the pointer. Edit the operand on line $203f, enter the
symbol "PTR1", and in the Symbol Shorcuts section, click "Set operand
AND create project symbol". Click OK. Note that operand on line $2043
has changed to "PTR1+1".</p>
<p>Let's give the pointer a name. Select line $203d, and use
Actions &gt; Edit Local Variable Table to create an empty table.
Click "New Symbol" on the right side. Set the Label field to "PTR1",
the Value field to $02, and the width to 2 (it's a 2-byte pointer). Leave
the Address button selected. Click "OK" to create the entry, and then
"OK" to update the table.</p>
<p>There's now a ".var" statement (similar to a .equ) above line $203d,
and the stores to $02/$03 have changed to "PTR1" and "PTR1+1".</p>
<p>Double-click on the JSR on line $2045 to jump to L209A. This just
loads a value from $3000 into the accumulator and returns, so not much
to see here. Hit the back-arrow in the toolbar to jump back to the JSR.</p>
@ -477,10 +483,14 @@ to see here. Hit the back-arrow in the toolbar to jump back to the JSR.</p>
0 and 3, then doubles it and uses it as an index into PTR1. We know PTR1
points to XDATA, which looks like it has some 16-bit addresses. The
values loaded are stored in two more zero-page locations, $04-05.</p>
<p>$04 is being displayed as "PTR1+2", which isn't quite right, so let's
fix that. Double-click on the operand of address $204e, set the symbol
to "PTR2", and again click "Set operand AND create project symbol".
Click OK. That looks better.</p>
<p>Let's make these a pointer as well. Double-click the operand on
line $204e ("$04"), and click "Create Local Variable". Set the Label
to "PTR2" and the width to 2. Click "OK" to create the symbol, then
"OK" to close the operand editor, which should still be set to Default --
we didn't actually edit the operand, we just used the operand edit
dialog as a convenient way to create a local variable table entry. All
accesses to $04/$05 now use PTR2, and there's a new entry in the local
variable table we created earlier.</p>
<p>The next bit of code copies bytes from PTR2 to $0400, stopping when it
hits a zero byte. Looks like this is copying null-terminated strings.
@ -488,16 +498,16 @@ This confirms our idea that XDATA holds 16-bit addresses, so let's
format it. Select lines $2063 to $2066, and Actions &gt; Edit Operand.
It should say "8 bytes selected" at the top. Select "16-bit words,
little-endian", and then from the Display As box, select "Address".
Click OK. XDATA should now be four <code>.dd2</code> 16-bit addresses.
Click "OK". XDATA should now be four <code>.dd2</code> 16-bit addresses.
If you scroll up, you'll see that the .ZSTR strings near the top now have
labels that match the labels in XDATA.</p>
labels that match the operands in XDATA.</p>
<p>Now that we know what XDATA holds, let's rename it. Change the label
to STRADDR. The symbol parts in the operands at $203d and $2041 update
automatically.</p>
<p>Let's pause briefly to look at the cycle-count feature. Use
Edit &gt; Settings to open the app settings panel, then select the
Asm Config tab. Click the "Show cycle counts" checkbox, then click OK.</p>
Asm Config tab. Click the "Show cycle counts" checkbox, then click "OK".</p>
<p>Every line with an instruction now has a cycle count on it. The cycle
counts are adjusted for everything SourceGen can figure out. For example,
the BEQ on line $205a shows "2+" cycles, meaning that it takes at least two
@ -527,19 +537,20 @@ the flags should be before the instruction is executed. For each flag,
we can override the default behavior and specify that the flag is
clear (0), set (1), or indeterminate (could be 0 or 1). In this case,
we know that the self-modified code will be loading a non-zero value, so
in the "Z" column click on the button in the "Zero" row. Click OK. The
in the "Z" column click on the button in the "Zero" row. Click "OK". The
BNE is now an always-taken branch, and the code list rearranges itself
appropriately (and the cycle count is now 3).</p>
<p>Continuing on, the code at $2079 touches a few consecutive locations. Edit
the label on line $2074, setting it to "VAR". Notice how the references
the label on line $2074, setting it to "STUFF". Notice how the references
to $2074 through $2077 have changed from auto-generated labels to
references to VAR. For some projects this may be undesirable. Use
references to STUFF. For some projects this may be undesirable. Use
Edit &gt; Project Properties, then in the Analysis Parameters box
un-check "Seek nearby targets", and click OK. You'll notice that the
references to $2075 on have switched back to auto labels. Furthermore, if
you scroll up, you'll see that the stores to PTR1+1 and PTR2+1 are now
just stores to $03 and $05.</p>
un-check "Seek nearby targets", and click "OK". You'll notice that the
references to $2075 and later have switched back to auto labels. If
you scroll up, you'll see that the references to PTR1+1 and PTR2+1 were
not affected, because local variables use explicit widths rather
than the "nearby" logic.</p>
<p>The nearby-target behavior is generally desirable, because it lets you
avoid explicitly labeling every part of a multi-byte data item. For now,
use Edit &gt; Undo to switch it back on.</p>
@ -564,6 +575,10 @@ all aspects of SourceGen in the manual.</p>
<p>While you can do some fancy things, nothing you do will alter the
data file. The assembled output will always match the original. So
don't be afraid to play around.</p>
<p>If you want to work on something large over a long period, save your
progress by putting the .dis65 project into a source code control system
like git. Project files are stored in a text format that, while not meant
to be human-readable, will yield reasonable diffs.</p>
</div>

View File

@ -198,7 +198,7 @@ limitations under the License.
<!-- local variable controls -->
<GroupBox Grid.Column="1" Grid.Row="4" Margin="0,4,0,0" Padding="2,4" Header="Local Variable">
<StackPanel>
<TextBlock Text="Operand is not a zero page address or stack relative" TextWrapping="Wrap"
<TextBlock Text="Operand is not a zero page address or stack-relative constant" TextWrapping="Wrap"
Visibility="{Binding ShowLvNotApplicable, Converter={StaticResource BoolToVis}}"/>
<TextBlock Text="No local variable tables have been defined before this point" TextWrapping="Wrap"
Visibility="{Binding ShowLvTableNotFound, Converter={StaticResource BoolToVis}}"/>

View File

@ -912,7 +912,11 @@ namespace SourceGen.WpfGui {
DefSymbol origSym = mEditedProjectSymbol;
if (origSym == null) {
// Need to start with a symbol so we can set the value field.
origSym = new DefSymbol("SYM", mOperandValue, Symbol.Source.Project,
string symName = "SYM";
if (!string.IsNullOrEmpty(SymbolLabel)) {
symName = SymbolLabel; // may not be valid, but it doesn't have to be
}
origSym = new DefSymbol(symName, mOperandValue, Symbol.Source.Project,
Symbol.Type.ExternalAddr, FormatDescriptor.SubType.None,
string.Empty, string.Empty);
}