prng_6502 icon indicating copy to clipboard operation
prng_6502 copied to clipboard

Reseeding implementation and commentary needed

Open bbbradsmith opened this issue 2 years ago • 0 comments

After seeding, it can take many iterations for the apparent effect of the seed to "warm up", and seed values that are close will be seen to fail to diverge much when compared at equal numbers of steps.

This correlation was discovered when trying to use the LFSR as a hash of a 2D X/Y to a random value. Patterns show up easily when plotting 16-bit X<<8 + Y seeds, and can't really be eradicated just by iterating the LFSR.

After investigating for a while, I came up with a method of ticking it once for each bit in the LFSR, but swapping the bytes whenever the middle bit was set.

16-bit python method:

def galois16(s,t):
    for i in range(t):
        f =        s & 0x8000
        s = (s << 1) & 0xFFFF
        if f:     s ^= 0x0039
    return s

def swap16(s):
    return ((s << 8) | (s >> 8)) & 0xFFFF

def randxy(x,y):
    x = x & 0xFF
    y = y & 0xFF
    s = (x << 8) | y
    for i in range(16):
        if (s & 0x80):
            s = swap16(s)
        s = galois16(s,1)
    return s & 0xFF

32-bit python method.

def galois32(s,t):
    for i in range(t):
        f =        s & 0x80000000
        s = (s << 1) & 0xFFFFFFFF
        if f:     s ^= 0x000000C5
    return s

def swap32(s):
    return \
        (((s >>  0) & 0xFF) << 16) | \
        (((s >>  8) & 0xFF) << 24) | \
        (((s >> 16) & 0xFF) <<  0) | \
        (((s >> 24) & 0xFF) <<  8)
    
def randxy(x,y):
    x = x & 0xFF
    y = y & 0xFF
    s = (x << 24) | (y << 16) | (x << 8) | (y << 0)
    for i in range(32):
        if (s & 0x8000):
            s = swap32(s)
        s = galois32(s,1)
    return s & 0xFF

A method for the 24-bit one must also be devised and tested. (The byte swapping configuration matters, so the solution might not be obvious.) Also, should put an | 1 on the seed setup so that X=0/Y=0 doesn't make a dead seed.

Probably want to place the low byte of seed in the middle byte to trigger the swap quickly.

Need to create 6502 implementations of the above, and also add documentation about this need, since this inefficiency of seed setup is important for the user to know.

bbbradsmith avatar Jan 21 '23 03:01 bbbradsmith