- stronger randomness
- runs in linear time?
- fewer bytes
- fewer cycles
8-bit random number generator
Re: 8-bit random number generator
White Flame wrote:
They're tested to go through all 256 or 65535 numbers uniquely before repeating (and different EOR values order those chains differently), so they're good for doing certain utility or game things, like a fade-out dither.
White Flame wrote:
By the way, what's "better"? Stronger randomness, smaller time/memory footprint, or some other property like the above?
Re: 8-bit random number generator
There is a thorough, if rather verbose, summary of PRNG criteria here: http://pracrand.sourceforge.net/RNG_engines.txt
Re: 8-bit random number generator
Bob Jenkins has a 32-bit random number generator: http://burtleburtle.net/bob/rand/smallprng.html
It's perhaps more complicated than you'd want to run on a 6502, but it's still a lot simpler than Mersenne Twister. It has 16 bytes of state (organized as four 32-bit integers).
It's perhaps more complicated than you'd want to run on a 6502, but it's still a lot simpler than Mersenne Twister. It has 16 bytes of state (organized as four 32-bit integers).
Re: 8-bit random number generator
chitselb wrote:
This is on page 172 of Butterfield's "First Book of KIM-1"
Quote:
...it won't "lock up" so that the same number starts coming out over and over again...
That routine is a variant of a lagged Fibonacci generator, and lagged Fibonacci generators are notoriously tricky to initialize.
Re: 8-bit random number generator
I think PRNGs are rather like crypto: it's fun to roll your own, but not "safe" - there are too many pitfalls. And you certainly need to know what it is you care about: speed, size, safety.
I get the impression LFSRs date back to very early digital electronics, when shifting was not only easy, but natural, because machinery was often bit-serial. They remain a very good choice for 6502, because shifting is still cheap and natural. Anything based on multiplication comes from a later era, when machines could multiply cheaply - as we know, the 6502 doesn't have a multiply instruction.
I would go for LFSR myself, but as noted above, you need more bits in your shift register than you plan to pull out, and you need to spin it at least once per bit. It'll still be faster than naive multiplication.
And as also noted, initialisation is important - even more so if you care about the first few numbers produced.
I get the impression LFSRs date back to very early digital electronics, when shifting was not only easy, but natural, because machinery was often bit-serial. They remain a very good choice for 6502, because shifting is still cheap and natural. Anything based on multiplication comes from a later era, when machines could multiply cheaply - as we know, the 6502 doesn't have a multiply instruction.
I would go for LFSR myself, but as noted above, you need more bits in your shift register than you plan to pull out, and you need to spin it at least once per bit. It'll still be faster than naive multiplication.
And as also noted, initialisation is important - even more so if you care about the first few numbers produced.
Re: 8-bit random number generator
GARTHWILSON wrote:
If you have a VIA whose T1 (timer 1) you can set to free-run, reading and using the T1 value in part of your algorithm adds randomness since the times you read it will be rather random. If you're using T1 for a software RTC (real-time clock) running on interrupts, there is the slight problem that reading it just as it's about to generate an interrupt will clear the interrupt condition and make your RTC miss that tick. The chance is about .002% in my case where I have 100 ticks per second on a 5MHz computer. If that risk is too high, you might want to use a second VIA's T1.
Code: Select all
LDX randindex
DEX
BPL *+4
LDX #12
STX randindex
LDA randtab,X
EOR via_t1l
STA randtab,X
RTS
randtab:
; 13 random bytes
Re: 8-bit random number generator
GARTHWILSON wrote:
reading and using the T1 value in part of your algorithm adds randomness
My RNG involved other factors as well. Like a free-running VIA timer, the garbage character itself isn't random but the jitter in the sample timing tends to scramble things somewhat. I don't recall the recipe I used, but it served the purpose at the time!
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
Re: 8-bit random number generator
How about a white noise generator as the base for true random numbers?
http://holdenc.altervista.org/avalanche/
http://holdenc.altervista.org/avalanche/
6502 sources on GitHub: https://github.com/Klaus2m5
Re: 8-bit random number generator
There's the idea of 'mixing' in random number generators, especially in a crypto context, which is generally rather more involved than just xoring in some other sources of entropy, because you'd like to keep all the bits you have and add in the bits you are getting. A simple xor might cancel out, whereas hashing the two items together usually has the desired effect of every input bit having an effect, and also every output bit being affected by every input bit.
So, if you have some approach to mixing that you feel happy with, you can bring in timings from the outside world (keyboard, network, disk) quite safely and usefully, and you don't even have to reduce them to the few bits of entropy they represent.
You can also mix in from a biased noise source (which is why I mention it) - it's a good way to 'whiten' any patterns which the source might have.
Although almost no-one would need crypto-strength random numbers or mixing, it's at least as good as it needs to be, and if your code finds its way into a gambling machine, it's a good idea.
So, if you have some approach to mixing that you feel happy with, you can bring in timings from the outside world (keyboard, network, disk) quite safely and usefully, and you don't even have to reduce them to the few bits of entropy they represent.
You can also mix in from a biased noise source (which is why I mention it) - it's a good way to 'whiten' any patterns which the source might have.
Although almost no-one would need crypto-strength random numbers or mixing, it's at least as good as it needs to be, and if your code finds its way into a gambling machine, it's a good idea.
Re: 8-bit random number generator
Looking through old threads, I see Bruce has written something substantial about random number generators for 6502:
Ref these threads:
- combined Tausworthe PRNGs
Attempting to code a password secure OS.- (which links to this article by the late Lee Davison now found in the wayback machine archive: 6502 8 bit PRNG
Re: 8-bit random number generator
Back in the day, when 15 year old me was writing little hobby games on the Atari 800XL, my goto RNG was:
Or, in other words:
If you call this function 256 times, you'll get all 256 possible values. It was good enough for what I was doing at the time.
Code: Select all
uint8_t next_rnd(void)
{
static uint8_t rnd;
rnd = rnd * 5 + 17;
return rnd;
}
Code: Select all
RND: .BYTE 0
NEXT_RND:
LDA RND
LSL A ; A = RND * 2
LSL A ; A = RND * 4
CLC
ADC RND ; A = RND * 5
CLC
ADC #17 ; A = RND * 5 + 17
STA RND
RTS
Re: 8-bit random number generator
I like the Batari Basic rand16
It's just a 16 bit LFSR that shifts the two bytes in opposite directions
and XORs them for an 8bit return value
This is an interesting read hmc-cs-2014-0905.pdf
It's just a 16 bit LFSR that shifts the two bytes in opposite directions
and XORs them for an 8bit return value
Code: Select all
lda seedhi
lsr
rol seedlo
bcc noeor
eor #$B4
noeor
sta seedhi
eor seedlo
This is an interesting read hmc-cs-2014-0905.pdf
-
White Flame
- Posts: 704
- Joined: 24 Jul 2012
Re: 8-bit random number generator
If that seed is ever 0000, then it'll stay fixed at that value and never change.
Re: 8-bit random number generator
Thanks for the link to PCG, bogax. Some more reading:
That blogger, Daniel Lemire, also did a survey:
One thing we're up against is that most modern work on PRNGs will be for 64 bit machines with barrel shifters and fast multiply and divide. Even if for 32 bit machines, the approaches might not be good for 6502.
Another thing to note: if you just want a stream of random bits, it's a waste to compute 16 or 32 and then just use one bit. Same for two or three bits. Unfortunately to roll a six-sided die you need to take all the bits and reduce them to six cases, because six isn't a power of two.
Another thing to note: if you just want a stream of random bits, it's a waste to compute 16 or 32 and then just use one bit. Same for two or three bits. Unfortunately to roll a six-sided die you need to take all the bits and reduce them to six cases, because six isn't a power of two.
Re: 8-bit random number generator
White Flame wrote:
If that seed is ever 0000, then it'll stay fixed at that value and never change.
It's a cool little function.