I became interested in string reversal, a common interview question I remember getting, while investigating methods of converting integers to strings. In the discussion thread I started ^{[1]} I used disassembled code from MSC 5.1's itoa() routine. I always feel guilty using someone else's code verbatim in projects written from scratch, even if it was assembly code. Below is the inner loop (14 bytes) assuming a load address of 0x100 using DEBUG.
Code:0100 DEC DI 0101 LODSB 0102
I finally reached back into some of my first assembler ^{[1]} to write a routine called cubicnom() that generates a random cubic polynomial as the title implies. This pulls together several recent bits of code to seed the random number generator using a string and sprintf the results to a location in memory.
First, here's a random() function which accepts range parameters BX to CX. Thus if I pass in 1 and 9, respectively, then I'll get back
Random numbers are great but sometimes you want them to be consistently random (an oxymoron!) so that you can rely on their pattern being the same. For example, in Magenta's Maze everything is generated from random numbers that are seeded by the spell name. This is a string which is boiled down to an integer that is used to reset the pseudo-random number generator. Thus, the level generated for a certain string is always the same even across computers and time.
In the first version,
The puzzles of Magenta's Maze are generated using the barely sufficient rand() function supplied by MSC 5.1. There are some issues with this, most notably that the highest bit of the 16-bit word output is always zero. The way we C programmers were taught to use this function was to modulus the result by the maximum amount desired thus providing 0 to N - 1 (where N is the maximum). This is unfortunately how Magenta's Maze uses it to place objects within the map and rotate the magic circles.
I've been poking around for a quick way to convert 16-bit words into digit characters a la the itoa() function in C. ^{[1]} I thought and searched a lot around dividing by constants and clever ways of converting numbers to strings. In the end, I chose the K&R method as the base for my algorithm ^{[2]} which goes like this:
- Divide number by base (10).
- Write remainder as next digit (converting to ASCII by adding 30h).
- Use quotient as number and repeat loop if non-zero.
- Reverse