Extension Scripts
Some repetitive formatting tasks can be handled with automatic scripts. This is especially useful for inline data, which can confuse the code analyzer.
An earlier tutorial demonstrated how to manually mark bytes as inline data. We're going to do it a faster way. For this tutorial, start a new project with the Generic 6502 profile, and in the SourceGen Examples/Tutorial directory select "Tutorial4".
Take a look at the disassembly listing. The file starts with a
JSR
followed by a string that begins with a small number.
This appears to be a string with a leading length byte. We want to load
a script that can handle that, so use
Edit > Project Properties, select the
Extension Scripts tab, and click
Add Scripts from Runtime. The file
browser opens in the RuntimeData directory. Open the
"Common" folder, select the file
"StdInline.cs", click Open,
then OK.
Nothing happened. If you look at the script with an editor (and you
know some C#), you'll see that it's looking for a JSR
to a
function that begins with certain prefixes. For ASCII length-delimited
strings, the prefix is InA1_
. So let's set a label.
Double-click the JSR
opcode on line $1000
to jump to address $1036. The only thing there is an RTS
.
It's supposed to be a routine that prints a string with a leading length
byte, but for the sake of keeping the example code short it's just a
place-holder. Use the curly toolbar arrow
(or Alt+LeftArrow) to jump back to $1000.
This time, double-click the JSR
operand
("L1036") to edit the operand.
Click Create Label, and enter InA1_PrintString.
Remember that labels are case-sensitive;
you must enter it exactly as shown. Hit OK to accept the label,
and OK to close the operand editor.
If all went well, address $1003
should now be an L1 string "How long?
", and address $100D
should be another JSR
. This one appears to be followed
by an inline null-terminated string, so we'll need something
that handles that.
Double-click the operand on line $100D ("L1037
"),
click Create Label,
and set the label to "InAZ_PrintString1".
Hit OK twice. That formatted the first one and got us
to the next JSR
, at $1019. Repeat the process on line $1019
("L1038
"), setting the label to
"InAZ_PrintString2".
The last JSR
, at $1025, is followed by a 16-bit
pointer. Edit the operand, and use Create Label to
set the label at the target address to "InWA_StringPtr".
Because the bytes were formatted as an address and not a just a
16-bit value, a label was generated automatically.
What we'd really like to do in this case is to have it format the 16-bit address as a pointer, and format the data it points to as a null-terminated string. The StdInline script doesn't know how to do that though, so you'd need to write a custom script. (Scripts can format multiple data items, add symbolic references to labels and constants, and chase pointers around.)
The entire project is now nicely formatted. In a real project the
"Print Inline" locations would be actual print functions, not just RTS
instructions. There would likely be multiple JSR
s to the print function,
so labeling a single function entry point could format dozens of inline
strings and clean up the disassembly automatically. The reason for
allowing wildcard names is that some functions may have multiple
entry points or chain through different locations.
Extension scripts can make your life much easier, but they do require some programming experience. See the "Advanced Topics" section in the SourceGen manual for more details.