mirror of
https://github.com/fadden/6502bench.git
synced 2025-01-04 01:29:55 +00:00
Add advanced tutorial
Also, fixed a bug where the operand highlight would get out of sync after an edit.
This commit is contained in:
parent
fd6d8273a9
commit
acf19870c2
@ -141,9 +141,9 @@ namespace SourceGen.AppForms {
|
|||||||
this.seekAltTargetCheckBox.AutoSize = true;
|
this.seekAltTargetCheckBox.AutoSize = true;
|
||||||
this.seekAltTargetCheckBox.Location = new System.Drawing.Point(7, 45);
|
this.seekAltTargetCheckBox.Location = new System.Drawing.Point(7, 45);
|
||||||
this.seekAltTargetCheckBox.Name = "seekAltTargetCheckBox";
|
this.seekAltTargetCheckBox.Name = "seekAltTargetCheckBox";
|
||||||
this.seekAltTargetCheckBox.Size = new System.Drawing.Size(130, 17);
|
this.seekAltTargetCheckBox.Size = new System.Drawing.Size(121, 17);
|
||||||
this.seekAltTargetCheckBox.TabIndex = 3;
|
this.seekAltTargetCheckBox.TabIndex = 3;
|
||||||
this.seekAltTargetCheckBox.Text = "Seek alternate targets";
|
this.seekAltTargetCheckBox.Text = "Seek nearby targets";
|
||||||
this.seekAltTargetCheckBox.UseVisualStyleBackColor = true;
|
this.seekAltTargetCheckBox.UseVisualStyleBackColor = true;
|
||||||
this.seekAltTargetCheckBox.CheckedChanged += new System.EventHandler(this.seekAltTargetCheckBox_CheckedChanged);
|
this.seekAltTargetCheckBox.CheckedChanged += new System.EventHandler(this.seekAltTargetCheckBox_CheckedChanged);
|
||||||
//
|
//
|
||||||
|
@ -1021,6 +1021,7 @@ namespace SourceGen.AppForms {
|
|||||||
mReanalysisTimer.StartTask("Generate DisplayList");
|
mReanalysisTimer.StartTask("Generate DisplayList");
|
||||||
mDisplayList.GenerateAll();
|
mDisplayList.GenerateAll();
|
||||||
mReanalysisTimer.EndTask("Generate DisplayList");
|
mReanalysisTimer.EndTask("Generate DisplayList");
|
||||||
|
UpdateSelectionHighlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Project management
|
#endregion Project management
|
||||||
|
BIN
SourceGen/Examples/Tutorial/Tutorial2
Normal file
BIN
SourceGen/Examples/Tutorial/Tutorial2
Normal file
Binary file not shown.
87
SourceGen/Examples/Tutorial/Tutorial2.S
Normal file
87
SourceGen/Examples/Tutorial/Tutorial2.S
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
; Copyright 2018 faddenSoft. All Rights Reserved.
|
||||||
|
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
|
;
|
||||||
|
; Assembler: Merlin 32
|
||||||
|
|
||||||
|
INPUT equ $3000
|
||||||
|
OUTPUT equ $0400
|
||||||
|
PTR1 equ $02
|
||||||
|
PTR2 equ $04
|
||||||
|
|
||||||
|
START equ $2000
|
||||||
|
org START-2
|
||||||
|
|
||||||
|
dw START
|
||||||
|
|
||||||
|
sec
|
||||||
|
ror A
|
||||||
|
bmi skipstr
|
||||||
|
|
||||||
|
string0 asc 'first string',00
|
||||||
|
string1 asc 'another string',00
|
||||||
|
string2 asc 'string the third',00
|
||||||
|
string3 asc 'last string',00
|
||||||
|
|
||||||
|
skipstr
|
||||||
|
lda #<stringtab
|
||||||
|
sta PTR1
|
||||||
|
lda #>stringtab
|
||||||
|
sta PTR1+1
|
||||||
|
|
||||||
|
jsr thing
|
||||||
|
and #$03
|
||||||
|
asl A
|
||||||
|
tay
|
||||||
|
lda (PTR1),y
|
||||||
|
sta PTR2
|
||||||
|
iny
|
||||||
|
lda (PTR1),y
|
||||||
|
sta PTR2+1
|
||||||
|
|
||||||
|
ldy #$ff
|
||||||
|
]loop iny
|
||||||
|
lda (PTR2),y
|
||||||
|
beq copydone
|
||||||
|
ora #$80
|
||||||
|
sta OUTPUT,y
|
||||||
|
bne ]loop ;always taken
|
||||||
|
|
||||||
|
stringtab
|
||||||
|
dw string0
|
||||||
|
dw string1
|
||||||
|
dw string2
|
||||||
|
dw string3
|
||||||
|
|
||||||
|
copydone
|
||||||
|
lda #$ff
|
||||||
|
sta _mod+1
|
||||||
|
_mod lda #$00
|
||||||
|
bne skipbrk
|
||||||
|
|
||||||
|
middat ds 4
|
||||||
|
outdat ds 1
|
||||||
|
|
||||||
|
skipbrk
|
||||||
|
lda middat
|
||||||
|
ora middat+1
|
||||||
|
and middat+2
|
||||||
|
eor middat+3
|
||||||
|
|
||||||
|
ldx #$00
|
||||||
|
dfb $2c
|
||||||
|
rebr ldx #$01
|
||||||
|
sta outdat
|
||||||
|
lda INPUT
|
||||||
|
lsr A
|
||||||
|
lsr A
|
||||||
|
lsr A
|
||||||
|
lsr A
|
||||||
|
sta INPUT
|
||||||
|
bne rebr
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
thing
|
||||||
|
lda INPUT
|
||||||
|
rts
|
||||||
|
|
@ -636,7 +636,7 @@ L1005 EOR #$00
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>If you really don't like the way this works, you can disable the
|
<p>If you really don't like the way this works, you can disable the
|
||||||
search for alternate targets entirely from the
|
search for nearby targets entirely from the
|
||||||
<a href="settings.html#project-properties">project properties</a>.
|
<a href="settings.html#project-properties">project properties</a>.
|
||||||
Self-modifying code will always be adjusted because of the limitation
|
Self-modifying code will always be adjusted because of the limitation
|
||||||
on mid-instruction labels.</p>
|
on mid-instruction labels.</p>
|
||||||
|
@ -176,7 +176,7 @@ entry point hint) will use this value. This is chiefly of use for
|
|||||||
identify strings and regions filled with a single byte value. If it's
|
identify strings and regions filled with a single byte value. If it's
|
||||||
not checked, anything that isn't detected as code or explicitly formatted
|
not checked, anything that isn't detected as code or explicitly formatted
|
||||||
will simply be shown as a byte value.</p>
|
will simply be shown as a byte value.</p>
|
||||||
<p>If "seek alternate targets" is checked, the analyzer will try to use
|
<p>If "seek nearby targets" is checked, the analyzer will try to use
|
||||||
nearby labels for data loads and stores.</p>
|
nearby labels for data loads and stores.</p>
|
||||||
<p>The "minimum characters for string" setting determines how many
|
<p>The "minimum characters for string" setting determines how many
|
||||||
ASCII characters need to appear consecutively for the data analyzer to
|
ASCII characters need to appear consecutively for the data analyzer to
|
||||||
|
@ -195,7 +195,7 @@ it and check the References window.)</p>
|
|||||||
comment, and hit Enter. Your comment appears in the "comment" column.</p>
|
comment, and hit Enter. Your comment appears in the "comment" column.</p>
|
||||||
|
|
||||||
|
|
||||||
<h3>Editing Operands</h3>
|
<h3>Editing Instruction Operands</h3>
|
||||||
|
|
||||||
<p>The operand in the LDA instruction at line $2000 refers to an address
|
<p>The operand in the LDA instruction at line $2000 refers to an address
|
||||||
($3000) that isn't part of the file. We want to create an equate directive to
|
($3000) that isn't part of the file. We want to create an equate directive to
|
||||||
@ -239,7 +239,7 @@ symbolic reference, there's another option in the Edit Operand dialog that
|
|||||||
does it.)</p>
|
does it.)</p>
|
||||||
|
|
||||||
|
|
||||||
<h3>Editing Data Formats</h3>
|
<h3>Editing Data Operands</h3>
|
||||||
|
|
||||||
<p>There's some string and numeric data down at the bottom of the file. The
|
<p>There's some string and numeric data down at the bottom of the file. The
|
||||||
final string appears to be multiple strings stuck together. Notice that
|
final string appears to be multiple strings stuck together. Notice that
|
||||||
@ -247,8 +247,10 @@ the opcode for the very last line is '+', which means it's a continuation
|
|||||||
of the previous line. Long data items can span multiple lines, split
|
of the previous line. Long data items can span multiple lines, split
|
||||||
every 64 characters (including delimiters), but they are still single
|
every 64 characters (including delimiters), but they are still single
|
||||||
items: selecting any part selects the whole.</p>
|
items: selecting any part selects the whole.</p>
|
||||||
<p>Select the last line, then Edit > Edit Data Format. At the top of the
|
<p>Select the last line, then Actions > Edit Operand. You'll notice
|
||||||
dialog that appears, it will say "65 bytes selected". You can format this
|
that this dialog is much different from the one you got when editing the
|
||||||
|
operand of an instruction. At the top it will say "65 bytes selected". You
|
||||||
|
can format this
|
||||||
as a single 65-byte string, as 65 individual items, or various things
|
as a single 65-byte string, as 65 individual items, or various things
|
||||||
in between. For now, select "Single bytes", and then on the right,
|
in between. For now, select "Single bytes", and then on the right,
|
||||||
select "ASCII". Click "OK".</p>
|
select "ASCII". Click "OK".</p>
|
||||||
@ -256,8 +258,8 @@ select "ASCII". Click "OK".</p>
|
|||||||
same set of addresses.</p>
|
same set of addresses.</p>
|
||||||
<p>Select address $203D on its own, then Actions > Edit Label. Set the
|
<p>Select address $203D on its own, then Actions > Edit Label. Set the
|
||||||
label to "STR1". Move up a bit and select address $2030, then scroll to
|
label to "STR1". Move up a bit and select address $2030, then scroll to
|
||||||
the bottom and shift-click address $2070. Select Actions > Edit Data
|
the bottom and shift-click address $2070. Select Actions > Edit Operand.
|
||||||
Format. At the top it should now say, "65 bytes selected in 2 groups".
|
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
|
There are two groups because the presence of a label split the data into
|
||||||
two separate regions. Select "mixed ASCII and non-ASCII", then click
|
two separate regions. Select "mixed ASCII and non-ASCII", then click
|
||||||
"OK".</p>
|
"OK".</p>
|
||||||
@ -274,7 +276,7 @@ Format (or hit Ctrl+B).</p>
|
|||||||
<p>The data starting at $2025 appears to be 16-bit addresses that point
|
<p>The data starting at $2025 appears to be 16-bit addresses that point
|
||||||
into the table of strings, so let's format them appropriately.</p>
|
into the table of strings, so let's format them appropriately.</p>
|
||||||
<p>Select the line at $2025, then shift-click the line at $202E. Select
|
<p>Select the line at $2025, then shift-click the line at $202E. Select
|
||||||
Actions > Edit Data Format. If you selected the correct set of bytes,
|
Actions > Edit Operand. If you selected the correct set of bytes,
|
||||||
the top should say, "10 bytes selected". Click the
|
the top should say, "10 bytes selected". Click the
|
||||||
"16-bit words, little-endian" radio button, then over to the right, click
|
"16-bit words, little-endian" radio button, then over to the right, click
|
||||||
the "Address" radio button. Click "OK".</p>
|
the "Address" radio button. Click "OK".</p>
|
||||||
@ -307,12 +309,10 @@ it should always match exactly.)</p>
|
|||||||
<p>Click "Close" to close the window.</p>
|
<p>Click "Close" to close the window.</p>
|
||||||
|
|
||||||
|
|
||||||
<h3>Go Forth</h3>
|
<h3>End of Part One</h3>
|
||||||
|
|
||||||
<p>That's it for the basic tutorial. Play with the program some more to see
|
<p>At this point you know enough to work with a SourceGen project. Continue
|
||||||
what it can do, or do something wild like read the manual.</p>
|
on to the next tutorial to learn more.</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.</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="advanced-features">Advanced Features</a></h2>
|
<h2><a name="advanced-features">Advanced Features</a></h2>
|
||||||
@ -390,8 +390,161 @@ code entry point hint -- but did several of them at once.</p>
|
|||||||
SourceGen asks if you want to continue, click OK.</p>
|
SourceGen asks if you want to continue, click OK.</p>
|
||||||
|
|
||||||
|
|
||||||
<h3>[to be continued]</h3>
|
<h3>Going Deeper</h3>
|
||||||
|
|
||||||
|
<p>Start a new project. Select "Generic 6502". For the data file, navigate
|
||||||
|
to the Examples directory, then from the Tutorials directory
|
||||||
|
select "Tutorial2".</p>
|
||||||
|
<p>The first thing you'll notice is that we immediately ran into a BRK,
|
||||||
|
which is a pretty reliable sign that we're not in a code section. The
|
||||||
|
generic profile puts a code entry point hint on the first byte, but that's
|
||||||
|
wrong here. This particular file begins with <code>00 20</code>, which
|
||||||
|
could be a load address (C64 binaries look like this). So let's start
|
||||||
|
with that assumption.</p>
|
||||||
|
<p>Click on the first line of code at address $1000, and select
|
||||||
|
Actions > Remove Hints. The $20 got absorbed into a string. The string
|
||||||
|
is making it hard to manipulate the next few bytes, so let's fix that by
|
||||||
|
selecting Edit > Toggle Data Scan. This turns off the feature that
|
||||||
|
looks for strings and .FILL regions, so now each uncategorized byte is
|
||||||
|
on its own line.</p>
|
||||||
|
<p>Select the first two lines, use Actions > Edit Operand, and format
|
||||||
|
it as a 16-bit little-endian word. We're assuming this is the load
|
||||||
|
address for the data that follows, so click on the line with address
|
||||||
|
$1002, select Actions > Set Address, and enter "2000". With that
|
||||||
|
line still selected, use Actions > Hint As Code Entry Point to identify
|
||||||
|
it as code.</p>
|
||||||
|
<p>That looks better, but it's branching off the bottom of the screen
|
||||||
|
(unless you have a really tall screen or small fonts) because of all the
|
||||||
|
intervening data. Use Edit > Toggle Data Scan to turn the string
|
||||||
|
finder back on.</p>
|
||||||
|
|
||||||
|
<p>There are four strings starting at address $2004, each of which is
|
||||||
|
followed by $00. These look like null-terminated strings, so let's make
|
||||||
|
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. click on
|
||||||
|
"last string").</p>
|
||||||
|
<p>The Edit Data Format 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 control key down, and double-click
|
||||||
|
on the operand on line $203c ($00). Control-clicking adds the line to
|
||||||
|
the selection, and double-clicking the operand reopens the dialog. 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.</p>
|
||||||
|
|
||||||
|
<p>It's wise to save your work periodically. Use File > Save to create
|
||||||
|
a project file for Tutorial2.</p>
|
||||||
|
|
||||||
|
<h4>Pointers and Parts</h4>
|
||||||
|
|
||||||
|
<p>Let's move on to the code at $203d. It starts by storing a couple of
|
||||||
|
values into direct page address $02/03. This appears to be setting up a
|
||||||
|
pointer to $2063, which is a data area inside the file. So let's make it
|
||||||
|
official.</p>
|
||||||
|
<p>Select line $2063, and use Actions > 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,
|
||||||
|
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 #<XDATA</code>
|
||||||
|
and <code>LDA #>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>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>
|
||||||
|
<p>The next bit of code masks the accumulator so it holds a value between
|
||||||
|
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>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.
|
||||||
|
This confirms our idea that XDATA holds 16-bit addresses, so let's
|
||||||
|
format it. Select lines $2063 to $2066, and Actions > 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. If you scroll up, you'll see that your .ZSTR strings now have
|
||||||
|
labels that match the labels 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 > Settings to open the app settings panel, then select the
|
||||||
|
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
|
||||||
|
cycles but might take more. That's because conditional branches take an
|
||||||
|
extra cycles if the branch is taken. The BNE on line $2061" shows 3 cycles,
|
||||||
|
because we know that the branch is always taken.</p>
|
||||||
|
<p>The cycle-count comments are included in assembled output as well. If
|
||||||
|
you add an end-of-line comment, it appears after the cycle count.</p>
|
||||||
|
<p>Hit Ctrl+S to save your project. Make that a habit.</p>
|
||||||
|
|
||||||
|
<h4>Odds & Ends</h4>
|
||||||
|
|
||||||
|
<p>The rest of the code isn't really intended to do anything useful. It
|
||||||
|
just exists to illustrate some odd situations.</p>
|
||||||
|
<p>Look at the code starting at $206b. It ends with a BRK at $2074, which
|
||||||
|
as noted earlier is a bad sign. If you look up two lines, you'll see that
|
||||||
|
it's loading the accumulator with zero, then doing a BNE, which should never
|
||||||
|
be taken (note the cycle count for the BNE is 2). The trick is in the
|
||||||
|
two lines before that, which use self-modifying code to change the LDA
|
||||||
|
immediate operand from $00 to $ff. The BNE is actually a branch-always.</p>
|
||||||
|
<p>We can fix this by correcting the status flags. Select line $2072,
|
||||||
|
and then Actions > Override Status Flags. This lets us specify what
|
||||||
|
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
|
||||||
|
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
|
||||||
|
to $2074 through $2077 have changed from auto-generated labels to
|
||||||
|
references to VAR. For some projects this may be undesirable. Use
|
||||||
|
Edit > 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>
|
||||||
|
<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 > Undo to turn it back on.</p>
|
||||||
|
|
||||||
|
<p>The code at $2085 looks a bit strange. LDX, then a BIT with a weird
|
||||||
|
symbol, then another LDX. If you look at the "bytes" column, you'll notice
|
||||||
|
that the three-byte BIT instruction has only one byte on its line. The
|
||||||
|
trick here is that the <code>LDX #$01</code> is embedded inside the BIT
|
||||||
|
instruction. When the code runs through here, X is set to $00, then
|
||||||
|
the BIT instruction sets some flags, then the STA runs. Several lines
|
||||||
|
down there's a BNE to $2088, which is in the middle of the BIT instruction.
|
||||||
|
It loads X with $01, then also continues to the STA.</p>
|
||||||
|
<p>Embedded instructions are unusual but not unheard-of. When you see the
|
||||||
|
extra symbol in the opcode field, you need to look closely at what's going
|
||||||
|
on.</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Go Forth</h3>
|
||||||
|
|
||||||
|
<p>That's it for the tutorials. There's significantly more detail on
|
||||||
|
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>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user