6502bench

- Introduction
- About Disassembly
- Using SourceGen
  - Moving Around
  - Simple Edits
  - Labels & Symbols
  - Editing Data Operands
  - Generating Code
- Digging Deeper
  - String Formatting
  - Local Variables
  - Inline Data
  - Odds & Ends
- Advanced Topics
  - Address Tables
  - Extension Scripts
  - Visualizations
- Suggestions

## 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.)

« Previous Next »