mirror of
https://github.com/cc65/cc65.git
synced 2026-04-22 01:16:54 +00:00
rand() use XOR to break up unwanted pair correlation (#1107)
* rand() use XOR to break up unwanted pair correlation This form of rand() cannot return the same value twice in a row. Two additonal EOR instructions produce a more even distribution of successive pairs. see comments on #951 * rand.s document purpose of XOR * suggested srand() optimization: zero fill unnecessary * test to validate implementation of rand() * srand() improving behaviour and adding startup test * srand() with a tail call to rand() for better initial shuffle * srand() can fall through to rand() instead of tail call
This commit is contained in:
+15
-17
@@ -15,14 +15,14 @@
|
||||
; Multiplier must be 1 (mod 4)
|
||||
; Added value must be 1 (mod 2)
|
||||
; This guarantees max. period (2**32)
|
||||
; The lowest bits have poor entropy and
|
||||
; exhibit easily detectable patterns, so
|
||||
; only the upper bits 16-22 and 24-31 of the
|
||||
; 4-byte state are returned.
|
||||
; The quality of entropy in the bits of the seed are poorest in the lowest
|
||||
; bits, and best in the highest bits.
|
||||
;
|
||||
; The best 8 bits, 24-31 are returned in the
|
||||
; low byte A to provide the best entropy in the
|
||||
; most commonly used part of the return value.
|
||||
; The high 8 bits are used for the low byte A to provide the best entropy in
|
||||
; the most commonly used part of the return value.
|
||||
;
|
||||
; Finally XOR with the lower 2 bytes is used on the output, which breaks up
|
||||
; some minor deficient sequential patterns. (#951)
|
||||
;
|
||||
; Uses the following LCG values for ax + c (mod m)
|
||||
; a = $01010101
|
||||
@@ -42,10 +42,15 @@
|
||||
|
||||
; The seed. When srand() is not called, the C standard says that that rand()
|
||||
; should behave as if srand() was called with an argument of 1 before.
|
||||
rand: .dword 1
|
||||
rand: .dword $B5B5B4B4
|
||||
|
||||
.code
|
||||
|
||||
_srand: sta rand+0 ; Store the seed
|
||||
stx rand+1
|
||||
sta rand+2 ; argument << 16 is convenient fill for MSW
|
||||
stx rand+3
|
||||
; fall through to rand() to sufficiently "shuffle" first rand() result
|
||||
_rand: clc
|
||||
lda rand+0
|
||||
adc #$B3
|
||||
@@ -54,18 +59,11 @@ _rand: clc
|
||||
sta rand+1
|
||||
adc rand+2
|
||||
sta rand+2
|
||||
eor rand+0
|
||||
and #$7f ; Suppress sign bit (make it positive)
|
||||
tax
|
||||
lda rand+2
|
||||
adc rand+3
|
||||
sta rand+3
|
||||
eor rand+1
|
||||
rts ; return bit (16-22,24-31) in (X,A)
|
||||
|
||||
_srand: sta rand+0 ; Store the seed
|
||||
stx rand+1
|
||||
lda #0
|
||||
sta rand+2 ; Set MSW to zero
|
||||
sta rand+3
|
||||
rts
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user