Skip to content

Commit 8071c03

Browse files
author
Zeda
committed
Using Patrik Rak's 32-bit xorshift in the rand routine
1 parent b7b095a commit 8071c03

File tree

2 files changed

+40
-34
lines changed

2 files changed

+40
-34
lines changed

common/rand.z80

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,44 @@
11
#ifndef included_rand
22
#define included_rand
3+
34
rand:
4-
;Tested and passes all CAcert tests
5-
;Uses a very simple 32-bit LCG and 32-bit LFSR
6-
;it has a period of 18,446,744,069,414,584,320
7-
;roughly 18.4 quintillion.
8-
;LFSR taps: 0,2,6,7 = 11000101
9-
;323cc
10-
;Thanks to Runer112 for his help on optimizing the LCG and suggesting to try the much simpler LCG. On their own, the two are terrible, but together they are great.
11-
;Uses 64 bits of state
5+
; This rand routine combines Patrik Rak's fantastic 32-bit xorshift
6+
; (https://gist.github.com/raxoft/c074743ea3f926db0037) with a simple lcg for
7+
; extra smoothing.
8+
; It has a period of 281,474,976,645,120 and uses 48 bits of state
9+
; 42 bytes
10+
; 210cc
1211
ld hl,(seed0)
13-
ld de,(seed0+2)
1412
ld b,h
1513
ld c,l
16-
add hl,hl \ rl e \ rl d
17-
add hl,hl \ rl e \ rl d
14+
add hl,hl
15+
add hl,hl
1816
inc l
1917
add hl,bc
2018
ld (seed0),hl
21-
ld hl,(seed0+2)
22-
adc hl,de
23-
ld (seed0+2),hl
24-
ex de,hl
25-
;lfsr
26-
ld hl,(seed1)
27-
ld bc,(seed1+2)
28-
add hl,hl \ rl c \ rl b
29-
ld (seed1+2),bc
30-
sbc a,a
31-
and %11000101
19+
20+
; xorshift
21+
ld hl,(seed1) ; yw -> zt
22+
ld de,(seed1+2) ; xz -> yw
23+
ld (seed1+2),hl ; x = y, z = w
24+
ld a,l ; w = w ^ ( w << 3 )
25+
add a,a
26+
add a,a
27+
add a,a
3228
xor l
3329
ld l,a
30+
ld a,d ; t = x ^ (x << 1)
31+
add a,a
32+
xor d
33+
ld h,a
34+
rra ; t = t ^ (t >> 1) ^ w
35+
xor h
36+
xor l
37+
ld h,e ; y = z
38+
ld l,a ; w = t
3439
ld (seed1),hl
35-
ex de,hl
40+
41+
; Mix the xorshift and the lcg
3642
add hl,bc
3743
ret
3844
#endif

common/randinit.z80

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
#define included_randinit
33

44
randinit:
5-
ld a,r
6-
ld hl,seed0
7-
xor (hl) \ ld (hl),a \ inc hl
8-
xor (hl) \ ld (hl),a \ inc hl
9-
xor (hl) \ ld (hl),a \ inc hl
10-
xor (hl) \ ld (hl),a \ inc hl
11-
xor (hl) \ ld (hl),a \ inc hl
12-
xor (hl) \ ld (hl),a \ inc hl
13-
xor (hl) \ ld (hl),a \ inc hl
14-
or 97 ;no particular reason
15-
or (hl) \ ld (hl),a
5+
; need to make sure seed1 is non-zero
6+
ld hl,seed1
7+
ld a,(hl)
8+
inc hl
9+
or (hl)
10+
inc hl
11+
or (hl)
12+
inc hl
13+
or (hl)
14+
ret nz
15+
dec (hl)
1616
ret
1717
#endif

0 commit comments

Comments
 (0)