Creating Numeric Strings with Sprintf
By Anonymous
This article explains the Sprintf call in TI-89 and TI-92 Plus assembly, an operation that formats a string.
Many people are interested in knowing how to display numbers (for scoring routines and such) on the TI-89/92+, but don't want to go through the hassle of separating each number and placing it into a string backwards (like Jimmy Mårdell's Tetris scoring display routine) or else they want to display numbers greater than 655360. Jimmy Mårdell's routine, since it employs the divu instruction which is limited to answers that can be stored as 16-bit quotients and 16-bit remainders will not work because 655360/10 = 65536 or 16-bit plus 1. The results are a really weird looking string. Fortunately for Jimmy, no one will ever score that many points in Tetris, so you'll never notice this bug.
The solution? The sprintf ROM call!!! If you've programmed C before, you should know what sprintf is, but if not, here's the 411. Sprintf (string print formatted) is a command which prints data with a specific format to a string variable. These formats include number input, other string input, different numeric base input, and even tab spaces.
For our example program, we will display a large number stored in a variable.
sprintf1.asm include "doorsos.h" include "userlib.h" include "graphlib.h" xdef_main xdef_comment xdef_ti89 xdef_ti92plus _main: jsr graphlib::clr_scr move.l (integer),-(a7) pea sFormat(pc) pea string(pc) jsr doorsos::sprintf lea 12(a7),a7 WriteStr #0,#0,#4,string jsr userlib::idle_loop rts integer dc.l 123456789 sFormat dc.b "%lu",0 string ds.b 10 _comment dc.b "sprintf test",0 end
The program is very straight-forward. The graphlib and userlib libraries are employed to clear the screen and wait for user input. The WriteStr macro displays the string using the DrawStrXY ROM call. The important part is the sprintf code in the middle.
First, we move the integer (which MUST be a longword for this to work correctly) onto the stack. Then we push the string formatter onto the stack. The string formatter, named sFormat here is a long unsigned integer designated by %lu which is a C % replacement operand. You don't need to worry about this if you use longwords stored into variables. If you don't, then you better find a C reference book cause I don't have time to teach you the sprintf function in its entirety. Just think of the %lu as something that stands in for the number, specifically a long unsigned integer. Next we push the string's address onto the stack so it can be filled with the value of the sprintf command. Now we call sprintf. Sprintf takes the string formatter and replaces the operands in reverse fashion (i.e. we put the stuff in first, then the format, then the string instead of C fashion of string, then format, then stuff).
This is really all there is to know about integer strings, but there is a LOT more things you can do with sprintf. For examples, consult a C reference guide (NOT C++). A couple of minor points: 1) for this example to work, the variable MUST MUST MUST MUST be a longword and 2) you MUST use a variable, it can't just be a register. I don't know why exactly, but I've spend a lot of time debugging these problems, so just trust me.