6502bench

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" as the data file. You can choose to save the project file or not.

t4-add-inlinel1

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.

t4-stdinline-src

Nothing happened. If you look at the script with an editor (and you know some C#), you'll see that it's looking for JSR instructions that call functions whose names begin with certain strings. For ASCII strings prefixed with a 1-byte length, the appropriate function name 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.

t4-inlinel1-edit

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 (note the lower-case 'n'). Hit OK to accept the label, and OK to close the operand editor.

t4-inlinel1-done

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.

t4-inlinenull-done

Double-click the operand on line $100D ("L1037"), click Create Label, and set the label to "InAZ_PrintString1". Hit OK twice. That formatted the string that followed, and got us to the next JSR, at $1019. Repeat the process on line $1019 ("L1038"), setting the label to "InAZ_PrintString2".

t4-inlinemulti-done

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". This causes the two bytes to be formatted as a 16-bit address, rather than just a 16-bit value, so a label was generated automatically at the target address ("L102B").

It would be even more helpful if it formatted the data at $102B as a null-terminated string. The basic StdInline script doesn't happen to do that, but it's possible to do it with 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 JSRs 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 using name prefixes like InAZ_, rather than full function names, is that there may be more than one function with the same stack mechanics. Also, 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.

« Previous Next »