I've written a few functions that are a possible alternative.
This is the base function that does the hard work of generating a random number from 0-255 in the A register (or as a return value, conveniently enough). This is the same random number generator that Boriel is using, incidentally. (Based pretty much wholly on Patrik Rak's stream random generator).
FUNCTION FASTCALL randomBase () as uByte
random: ld hl,$A280 ; xz -> yw
ld de,$C0DE ; yw -> zt
ld (random+1),de ; x = y, z = w
ld a,e ; w = w ^ ( w << 3 )
ld a,h ; t = x ^ (x << 1)
rra ; t = t ^ (t >> 1) ^ w
ld h,l ; y = z
ld l,a ; w = t
;ret (Not necessary, since the compiler will add ret to the end)
This function will update the seed value based on the current frames counter. To improve randomness, get the user to have a human interaction that can take a variable amount of time and then run this.
SUB FASTCALL updateSeed()
REM Updates the random generator seed from the FRAMES system variable.
The above function depends on my timer function, which gets the value in FRAMES:
FUNCTION FASTCALL t() as uLong
This function returns a value from zero to the specified limit number (limit <= 255)
FUNCTION fastcall randomBin(limit as uByte) as uByte
RET Z ; Input zero, output zero.
LD B,A ; Save A
JR C, randomBinLoopExit
JR randomBinLoop ; loop back until we find a bit.
JR NC, randomBinRedoCall
it's worth noting that the issue with this is that it basically rolls a random, and if it's bigger than limit, it rolls another one. This could potentially take a while, and isn't guaranteed to be fast. Though the probability of failing to hit the zone is kept to 50%, so on average it will roll 1.5 random numbers, I think, per call. This should usually be faster than a floating point multiply, I believe.
If you do want a number a random number between 0 and 1, using FIXED is quite a lot faster than float. This routine uses randombase to do that:
FUNCTION FASTCALL randomFixed() as FIXED
dim time as uLong
DIM n as uInteger
DIM variable as uByte
for n=0 to 20000
REM One line of the following three:
20,000 loops took:
variable=rnd*128 => 1180 frames.
variable=randomFixed()*128 => 613 Frames (1.92 x faster)
variable=randomBin(128) => 74 frames. (this example is 16 x faster) (worst case averages 13x faster; best case averages 22x faster)
(This does vary by limit, but is never > 89 frames for any limit chosen. Can be as low as about 52. Average is about 64.)
All three, of course, return an integer from 0 to 127 (the last 0-128; this chosen because it's a worse case scenario for timing).
For scale, 20,000 loops calling randomBase takes 37 frames. Of course, this returns a number from 0-255 regardless, with no option to set the upper bound.