aboutsummaryrefslogtreecommitdiff
path: root/rand.s
diff options
context:
space:
mode:
authorB. Watson <yalhcru@gmail.com>2021-05-27 17:12:46 -0400
committerB. Watson <yalhcru@gmail.com>2021-05-27 17:12:46 -0400
commitdb18f631485eea0b1e7d6c8cf853ff4a281c2aba (patch)
tree745ce83b3c24eb8253b7c7097d9a36937b627a49 /rand.s
parent5b6f0359338c922f809c5133eb4c7efc61b3f21c (diff)
downloadtaipan-db18f631485eea0b1e7d6c8cf853ff4a281c2aba.tar.gz
cash_dirty, change random seeding, now 9006 bytes
Diffstat (limited to 'rand.s')
-rw-r--r--rand.s104
1 files changed, 103 insertions, 1 deletions
diff --git a/rand.s b/rand.s
index 6efcabd..f1b2c72 100644
--- a/rand.s
+++ b/rand.s
@@ -1,6 +1,5 @@
.export _randl, _rand1to3
- .import _rand
; .export _randb, _randi, _randl
; .export _rand1in5
; .export _randbit
@@ -37,6 +36,109 @@ _rand1to3:
ldx #0 ; now A is 1..3, but we have to force X to 0...
rts
+;;; This rand() function copied from cc65-2.19's libsrc/common/rand.s
+;;; and modified for my nefarious purposes.
+;;; srand() is not present (we don't use it).
+;
+; Random number generator
+;
+; Written and donated by Sidney Cadot - sidney@ch.twi.tudelft.nl
+; 2016-11-07, modified by Brad Smith
+; 2019-10-07, modified by Lewis "LRFLEW" Fox
+;
+; 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)
+; 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 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.
+;
+; 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.
+;
+
+ .export _rand, _randseed, _randseedl, _randseedh, _initrand, _addrandbits
+
+.bss
+
+; The seed. Not ANSI C compliant: we default to 0 rather than 1.
+_randseedl:
+_randseed: .res 4
+_randseedh = _randseed+2
+
+.code
+
+_rand: clc
+ lda _randseed+0
+ adc #$B3
+ sta _randseed+0
+ adc _randseed+1
+ sta _randseed+1
+ adc _randseed+2
+ sta _randseed+2
+ and #$7f ; Suppress sign bit (make it positive)
+ tax
+ lda _randseed+2
+ adc _randseed+3
+ sta _randseed+3
+ rts ; return bit (16-22,24-31) in (X,A)
+
+; Initially the seed comes from sequential reads of POKEY's random
+; register. It never returns 0 so we're guaranteed to have a usable
+; seed.
+_initrand:
+ ldx #3
+@l:
+ lda RANDOM
+ sta _randseed,x
+ dex
+ bpl @l
+ rts
+
+; Caller passes us a user keystroke as ATASCII, in A. We take bits 0
+; to 2, wait that many scanlines, get a random number from POKEY, and
+; EOR it into the _randseed byte pointed to by the low 2 bits of the
+; frame counter (RTCLOK+2).
+; Note that agetc() is still calling rand() on odd frames while all
+; this is going on.
+_addrandbits:
+ and #$07
+ tax
+@l1:
+ sta WSYNC
+ dex
+ bpl @l1
+ lda RTCLOK+2
+ and #$03
+ tax
+ lda RANDOM
+@e:
+ eor _randseed,x
+ beq @e ; if the result is 0, undo the eor.
+ sta _randseed,x
+ rts
+
+
;;; rest of file is commented out
; RANDOM is the POKEY LFSR read address. According to the POKEY data