The Programmer's Reference Guide gives three different argument ranges for RND(X):
- X>0 takes the internal seed and generates a new random number from it (the exact value of X doesn't matter at all),
- X=0 generates a random number from internal timers (bad!), and reinitialises the seed also from those timers,
- X<0 just re-initialises the seed from X, the result is unusable as random number.
Especially the commonly observed usage of RND(TI) just works the same as RND(1), it doesn't generate "more random" numbers!
Mike wrote:one needs to wonder if it actually even ever worked on real hardware
At the time I wrote this I (errorneously) thought RND(0) would take its result from the Jiffy IRQ timers. That would have implied a strong correlation time-wise between press of RETURN (due to the keyscan) and the calculation of RND(). However, that's not the case. As you've seen, your observation uncovered a true bug in the VIA emulation of VICE.
Coming back to the mainly intended handling of RND():
- You'd normally initialise the seed of RND() in the first line of the program with something like "X=RND(-TI):CLR", which uses the negative value of the jiffy clock since start-up to seed the random generator. The CLR command then clears the variables, so the program can build up the variable list once again in the order of most used variables first, if so desired. For this check the various threads discussing this.
- You'd then only ever use RND(1) generate a random number between 0 (inclusive) and 1 (exclusive), and use the standard construction of INT(RND(1)*(B-A+1))+A to get integer random numbers between A and B (both inclusive). The expression "(B-A+1)" would normally be written as constant number, as, for example, in
INT(RND(1)*6)+1 to get random numbers in the range 1..6.
...
That being said, the RND() function uses a *broken* variant of the linear-congruential generator. It exchanges bytes of the generated result, and thus brings parts of the random number into front that aren't nearly as random! Instead of a period of 2^32, RND() only produces tenthousands of small cycles, most of them in the order of ~58000 numbers, but there are also small cycles where RND() already repeats after ~750 numbers! Other numbers are only ever produced once, and then never again.
This is however an issue unrelated to VICE, and will also occur on real hardware. Only remedy is to use an own, better, generator.