As PRNGs seem to interest some people I also give you my
LFSR 64 which also dates from 1988,
It generates a random sequence of (2^64)-1 bits. It's a 64-bit GALOIS LFSR. Each call to the routine generates an 8-bit byte. We can therefore obtain (2^64)/8 bytes before repeating the sequence. There is no short cycle for all seed values.
First a 8-bytes seed must be put at
seed:The seed can vary from 1 to $FFFFFFFFFFFFFFFF but never 0 otherwise the LFSR produces only bits to 0.
Each call to the
start: function returns a pseudorandom byte in
rndbyte:First
init: must be call one time.
After
start: must be call for each generated byte (
rndbyte:) that can be use directly.
The test vector is :For a seed = $FFFFFFFFFFFFFFFF
the first 50 bytes are :Quote:
C4 B0 C2 1F BB C2 A2 D6 EA 28 87 FE 9E EA D6 14 D1 6E 0E 7A 46 84 41 FE 08 8A 49 74 4E 0E 07 7A 24 7F 23 05 6A 71 49 74 E0 05 A9 71 8A 74 23 05 A0 71
Code:
//----------------------------------------------------
// Pukall LFSR 64
// 1988
//----------------------------------------------------
//----------------------------------------------------
// Main Program
//----------------------------------------------------
init:
ldx #0
loop: jsr start
inx
cpx #64
bne loop
rts
start: lda #0
sta rndbyte
sta tmp
jsr begin
lda tmp
cmp #0
beq bit1
sta rndbyte
bit1: lda #0
sta tmp
jsr begin
lda tmp
cmp #0
beq bit2
lda rndbyte
ora #$2
sta rndbyte
bit2: lda #0
sta tmp
jsr begin
lda tmp
cmp #0
beq bit3
lda rndbyte
ora #$4
sta rndbyte
bit3: lda #0
sta tmp
jsr begin
lda tmp
cmp #0
beq bit4
lda rndbyte
ora #$8
sta rndbyte
bit4: lda #0
sta tmp
jsr begin
lda tmp
cmp #0
beq bit5
lda rndbyte
ora #$10
sta rndbyte
bit5: lda #0
sta tmp
jsr begin
lda tmp
cmp #0
beq bit6
lda rndbyte
ora #$20
sta rndbyte
bit6: lda #0
sta tmp
jsr begin
lda tmp
cmp #0
beq bit7
lda rndbyte
ora #$40
sta rndbyte
bit7: lda #0
sta tmp
jsr begin
lda tmp
cmp #0
beq ret
lda rndbyte
ora #$80
sta rndbyte
ret: rts
begin:
asl seed
rol seed+1
rol seed+2
rol seed+3
rol seed+4
rol seed+5
rol seed+6
rol seed+7
bcc not
lda seed
eor #$01
sta seed
lda seed+7
eor #$B0
sta seed+7
lda #1
sta tmp
not:
rts
seed: .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
tmp: .byte $00
rndbyte: .byte $00
A FIPS 140-2 test shows that bytes are seen as random:Quote:
rngtest: starting FIPS tests...
rngtest: bits received from input: 40000032
rngtest: FIPS 140-2 successes: 2000
rngtest: FIPS 140-2 failures: 0
rngtest: FIPS 140-2(2001-10-10) Monobit: 0
rngtest: FIPS 140-2(2001-10-10) Poker: 0
rngtest: FIPS 140-2(2001-10-10) Runs: 0
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=130.640; avg=3263.214; max=9536.743)Mibits/s
rngtest: FIPS tests speed: (min=1021.455; avg=16349.437; max=17147.717)Kibits/s
rngtest: Program run time: 2404057 microseconds
The optimized code :Code:
//----------------------------------------------------
// Pukall LFSR 64
// 1988
// Optimized by Teamtempest 2023
//----------------------------------------------------
//----------------------------------------------------
// Main Program
//----------------------------------------------------
init:
ldx #0
loop: jsr start
inx
cpx #64
bne loop
rts
start: lda #$00
sta rndbyte
lda #$01
sta mask
begin:
asl seed
rol seed+1
rol seed+2
rol seed+3
rol seed+4
rol seed+5
rol seed+6
rol seed+7
bcc not
lda seed
eor #$01
sta seed
lda seed+7
eor #$B0
sta seed+7
lda rndbyte
ora mask
sta rndbyte
not:
asl mask
bcc begin
rts
seed: .byte $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
mask: .byte $00
rndbyte: .byte $00