Saturday, June 21, 2014

NES String Utilities

There are a number of additional functions that may not be necessary but are nice to have if you are creating a text heavy game. One print-related function that I love to have, even if it is a very simple function, is a way of repeatedly printing an indicated character an indicated number of times. On the NES it is simply a matter of a loop sending the desired character to the PPU. Still, having it as a separate function will save a few bytes per use so it doesn't hurt to have as its own function.

PrintRepeatedChar: 
STA $2007
DEX 
BNE PrintRepeatedChar
RTS

If you are manipulating strings on the fly, something that will be used in the RPG that is my ultimate goal, appending characters and strings is handy. Appending a character simply requires that the terminating zero be replaced with the character to be appended and the byte after that character be replaced with a terminating zero. As this code is fairly similar to the AppendString function I will not bother showing the code here but feel free to look it up in the source file.

The AppendString function adds string pointed to by SOURCE_PTR to the end of the string pointed to by DEST_PTR. Note that DEST_PTR is modified  in the process to set up a call to StrNCpy. Our first goal is to find end index of DEST_PTR which points to the string being appended.

AppendString: 
LDY #0 
AppendString_loop: 
LDA [DEST_PTR],Y 
BEQ AppendString_doAppend 
INY 
CPY #$FF
BEQ AppendString_done 
JMP AppendString_loop


Once we know the length of the string we are appending we adjust the DEST_PTR to point to the end of the string. We can then simply call the StrNCpy function to finish. It is possible to save a few cycles by jumping to StrNCpy and taking advantage of its RTS but this is considered a bad practice that should only be used for optimizing.

AppendString_doAppend: 
; index in TEMP so it can be used with math instructions 
STY TEMP 
; Subtract index from 0 so we know maximum number of characters that 
; can be copied 
LDA #0 
SEC SBC TEMP 
; This is placed in X for subsequent StrNCpy call 
TAX 
; Add index to DEST_PTR 
LDA DEST_PTR 
CLC 
ADC TEMP 
BCC AppendString_StrNCpy 
INC DEST_PTR+1 
AppendString_StrNCpy: 
STA DEST_PTR ; now do the append via StrNCpy 
JSR StrNCpy 
AppendString_done: 
RTS


SubStr copies the middle portion of an existing string into a new string. Creating a new string from the middle portion of an existing string is another handy function but is really just a call to StrNCpy with an adjusted SOURCE_PTR. This is fairly straightforward code so will not be included here but is in the source file.

Finally the library includes a StrLength function. As we have done something like this in the Append String function we really don't need to show the code here. The big difference is we use SOURCE_PTR instead of DEST_PTR.

Now we have an adequate string library for our upcoming projects. Before we can get to creating the trivia game we still have one NES topic to cover. Controller input.

No comments: