*=============================================== * random.inc - Pseudo-random number generator. * Random number generation buffer. * Initialized with 100 bytes of random data (typed by hand). randbuf: fcb $3e,$10,$2a,$06,$72,$f1,$b4,$37,$29,$01 fcb $c0,$1a,$9e,$22,$70,$13,$d2,$fe,$21,$9e fcb $01,$91,$ee,$13,$db,$b6,$12,$03,$1a,$2f fcb $f0,$ba,$41,$06,$2e,$5f,$9f,$e1,$3d,$47 fcb $74,$29,$e2,$65,$7e,$43,$58,$91,$02,$63 fcb $43,$96,$25,$46,$7e,$10,$65,$55,$41,$50 fcb $21,$35,$7e,$9d,$02,$70,$b0,$b1,$dd,$0e fcb $34,$9f,$27,$83,$21,$97,$b6,$a0,$ff,$f1 fcb $29,$00,$f2,$e2,$77,$30,$6e,$b3,$88,$2f fcb $20,$61,$3f,$28,$69,$40,$71,$23,$d6,$b0 endbuf: equ * rindex: fcb 0 ; Current index into randbuf table. randval: rmb 1 ; Last random value returned. *----------------------------------------------------------------------- * Seed the random-number generator with the current time counter value. debug0: fcc "initializing random number generator" fcb EOT seedtime: ldx #debug0 jsr printmsg clra ; Clear MSB of D. ldab rindex ; Let D = rindex addd #randbuf ; Let D = &randbuf[rindex] xgdx ; Let X = &randbuf[rindex] cpx #(endbuf-1) ; Is X pointing to the last byte? blo nofix ; If so, dex ; decrement it by 1. nofix: ldd 0,x ; Let D = randbuf[rindex:rindex+1] addd TCNTH ; Let D = D + (current timer value) std 0,x ; Store D back where it came from. * Fall through to the next subroutine, to stir up the mix really good. stirgood: ldx #10 ; We'll stir the whole mix 10 times. stirring: jsr stironce ; Stir it once. dex bne stirring rts * "Stir" the random data set, touching every byte once. stironce: ldy #100 ; Do one complete cycle through the data. stirloop: jsr scramble ; Do a little bit of scrambling. dey bne stirloop rts * "Scramble" the data set locally a little bit. * Is careful to ensure all transformations are reversible. scramble: pshx pshy clra ldab rindex addd #(randbuf-100) xgdx ldaa 100,x bsr rotate adda 101,x eora 113,x suba 182,x bsr rotate adda 98,x eora 89,x suba 3,x bsr rotate staa randval staa 100,x xgdx subd #(randbuf-100) incb cmpb #100 blo ok clrb ok: stab rindex puly pulx * Rotate accumulator A left, rotating the MSB to the LSB rotate: lsla bcc done oraa #1 done: rts * Return a random byte in A. randbyte: jsr scramble ldaa randval rts * Return a random double-word in D. randword: jsr scramble ldaa randval psha jsr scramble ldab randval pula rts