2002-11-05 13:19:43 +00:00
|
|
|
;
|
2000-05-28 13:40:48 +00:00
|
|
|
; Randum number generator
|
|
|
|
;
|
|
|
|
; Written and donated by Sidney Cadot - sidney@ch.twi.tudelft.nl
|
2017-05-25 07:01:25 +00:00
|
|
|
; 2016-11-07, modified by Brad Smith
|
2019-10-09 06:42:50 +00:00
|
|
|
; 2019-10-07, modified by Lewis "LRFLEW" Fox
|
2000-05-28 13:40:48 +00:00
|
|
|
;
|
|
|
|
; May be distributed with the cc65 runtime using the same license.
|
|
|
|
;
|
|
|
|
;
|
|
|
|
; int rand (void);
|
|
|
|
; void srand (unsigned seed);
|
|
|
|
;
|
|
|
|
; Uses 4-byte state.
|
|
|
|
; Multiplier must be 1 (mod 4)
|
|
|
|
; Added value must be 1 (mod 2)
|
|
|
|
; This guarantees max. period (2**32)
|
2020-07-21 21:38:18 +00:00
|
|
|
; The quality of entropy in the bits of the seed are poorest in the lowest
|
|
|
|
; bits, and best in the highest bits.
|
2017-05-25 07:01:25 +00:00
|
|
|
;
|
2020-07-21 21:38:18 +00:00
|
|
|
; 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)
|
2019-10-09 06:42:50 +00:00
|
|
|
;
|
|
|
|
; Uses the following LCG values for ax + c (mod m)
|
|
|
|
; a = $01010101
|
|
|
|
; c = $B3B3B3B3
|
|
|
|
; m = $100000000 (32-bit truncation)
|
|
|
|
;
|
|
|
|
; The multiplier was carefully chosen such that it can
|
|
|
|
; be computed with 3 adc instructions, and the increment
|
|
|
|
; was chosen to have the same value in each byte to allow
|
|
|
|
; the addition to be performed in conjunction with the
|
|
|
|
; multiplication, adding only 1 additional adc instruction.
|
2000-05-28 13:40:48 +00:00
|
|
|
;
|
|
|
|
|
2013-05-09 11:56:54 +00:00
|
|
|
.export _rand, _srand
|
2000-05-28 13:40:48 +00:00
|
|
|
|
2002-11-05 13:19:43 +00:00
|
|
|
.data
|
2000-05-28 13:40:48 +00:00
|
|
|
|
2002-11-05 13:19:43 +00:00
|
|
|
; 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.
|
2020-07-21 21:38:18 +00:00
|
|
|
rand: .dword $B5B5B4B4
|
2000-05-28 13:40:48 +00:00
|
|
|
|
|
|
|
.code
|
|
|
|
|
2020-07-21 21:38:18 +00:00
|
|
|
_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
|
2020-07-21 21:44:36 +00:00
|
|
|
|
2013-05-09 11:56:54 +00:00
|
|
|
_rand: clc
|
2019-10-09 06:42:50 +00:00
|
|
|
lda rand+0
|
2019-10-08 03:37:34 +00:00
|
|
|
adc #$B3
|
2013-05-09 11:56:54 +00:00
|
|
|
sta rand+0
|
2019-10-09 06:42:50 +00:00
|
|
|
adc rand+1
|
2013-05-09 11:56:54 +00:00
|
|
|
sta rand+1
|
2019-10-08 03:37:34 +00:00
|
|
|
adc rand+2
|
2013-05-09 11:56:54 +00:00
|
|
|
sta rand+2
|
2020-07-21 21:38:18 +00:00
|
|
|
eor rand+0
|
2013-05-09 11:56:54 +00:00
|
|
|
and #$7f ; Suppress sign bit (make it positive)
|
|
|
|
tax
|
2019-10-08 03:37:34 +00:00
|
|
|
lda rand+2
|
|
|
|
adc rand+3
|
2013-05-09 11:56:54 +00:00
|
|
|
sta rand+3
|
2020-07-21 21:38:18 +00:00
|
|
|
eor rand+1
|
2016-07-12 00:48:47 +00:00
|
|
|
rts ; return bit (16-22,24-31) in (X,A)
|