Local Variables
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.
Select the line at address $2063, and use Actions > Edit Label to give it the label "XDATA?". The question mark on the end is there to remind us that we're not entirely sure what this is. Now edit the operand on line $203D, and set it to the symbol "XDATA", with the part "low". The question mark isn't really part of the label, so you don't need to type it here.
Edit the operand on line $2041,
and set it to "XDATA" with the part "high". (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 LDA #<XDATA?
and LDA #>XDATA?
.
Let's give the pointer a name. Select line $203D, and use Actions > Create Local Variable Table to create an empty table. Click New Symbol on the right side. Leave the Address button selected. Set the Label field to "PTR1", the Value field to "$02", and the width to "2" (it's a 2-byte pointer). Click "OK" to create the entry, and then "OK" to update the table.
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".
Double-click on the JSR
opcode on line $2045 to jump to
L20A7.
The code here 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
.
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.
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 format --
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.
The next section of code, at $2055, copies bytes from PTR2
to $0400, stopping when it hits a zero byte.
It 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.
The editor window should say "8 bytes selected" at the top.
Click the 16-bit words, little-endian radio button,
and then in the Display As box, click Address.
Click OK.
The values at XDATA
should now be four
.DD2
16-bit addresses.
If you scroll up, you'll see that the .ZSTR
strings
near the top now have labels that match the operands in XDATA
.
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.
Let's take a quick look at the cycle-count feature. Use Edit > Settings to open the app settings panel. In the Miscellaneous group on the right side, click the Show cycle counts for instructions checkbox, then click OK. (There's also a toolbar button for this.)
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 cycle if the branch is taken. The BNE
on line
$2061 shows 3 cycles, because we know that the branch is always
taken and doesn't cross a page boundary.
(If you want to see why it's always taken,
look at the value of the 'Z' flag in the "flags" column, which indicates
the state of the flags before the instruction on that line is executed.
Lower-case 'z' means the zero-flag is clear (0), upper-case 'Z' means it's
set (1). The analyzer determined that the flag was clear for instructions
following the BEQ
because we're on the branch-not-taken path.
The following instruction, ORA #$80
, cleared the 'Z' flag and
set the 'N' flag, so a BMI
would also be an always-taken branch.)
The cycle-count comments can be added to generated source code as well.
If you add an end-of-line comment, it appears after the cycle count. (Try it.)