# Getting random number from 6502 assembler

The SID chip can actually generate numbers that are more random than BASIC's pseudo-random numbers. Start the generator with:

LDA #$FF ; maximum frequency value STA$D40E ; voice 3 frequency low byte
STA $D40F ; voice 3 frequency high byte LDA #$80  ; noise waveform, gate bit off
STA $D412 ; voice 3 control register RTS  Then you can get random numbers whenever you want with: LDA$D41B ; get random value from 0-255


Thanks to Ross Ridge for suggesting that the called function was changing the value in the Y register. I knew it had to be something obvious!

By storing Y before the JSR, and restoring after, it now will iterate properly. Here is the quick fix:

Edit: Updated 7/10/17 - to show full code and incorporate JeremyP suggestion. This is essentially a coin flip iterator (50000 repetitions) for purposes of experimenting with random

.C 033c  A9 00       LDA #$00 .C 033e 85 FB STA$FB    ; set up register for counter
.C 0340  85 FC       STA $FC .C 0342 A2 C8 LDX #$C8   ; outer loop= 200
.C 0344  86 FD       STX $FD .C 0346 A0 FA LDY #$FA   ; inner loop=250
.C 0348  84 FE       STY $FE .C 034a 20 94 E0 JSR$E094  ; Get random# Vic20 Address (E09B for C64)
.C 034d  A5 63       LDA $64 .C 034f C9 80 CMP #$80   ; >128 = HEADS
.C 0351  90 0D       BCC $0360 ; else continue loop .C 0353 18 CLC ; increment 2 byte number .C 0354 A5 FB LDA$FB
.C 0356  69 01       ADC #$01 ; LSB .C 0358 85 FB STA$FB
.C 035a  A5 FC       LDA $FC .C 035c 69 00 ADC #$00   ; MSB
.C 035e  85 FC       STA $FC .C 0360 C6 FE DEC$FE
.C 0362  D0 E6       BNE $034A ; end inner loop .C 0364 C6 FD DEC$FD
.C 0366  D0 DE       BNE $0346 ; end outer loop .C 0368 60 RTS ; return to basic  I can get the random number by LDA$63 or LDA $64 inside the loop and use it for my purposes. This turned out to be a lot slower than expected, taking only half the time it would've taken in BASIC. The RND function takes a lot of cycles, however, I found this Compute! article which uses the SID chip as a random number generator. LDA #$FF  ; maximum frequency value
STA $D40E ; voice 3 frequency low byte STA$D40F ; voice 3 frequency high byte
LDA #$80 ; noise waveform, gate bit off STA$D412 ; voice 3 control register


Once turned on it generates numbers independently and doesn't have to be executed again. A loop that repeatadly calls LDA \$D41B will get you a new random number on each iteration. In my test 50,000 iterations took 1.25 seconds and million took a little over 24 seconds. Pretty impressive for a 1MHz computer!