I have been plundering around and trying to get random numbers. After thinking about it and not finding anything useful on the net I came up with this method:

- Get 3 random seed numbers, 1 from rasterline position, 2 from VIA counters (they are fetched at program start)

- Make 3 virtual "oscillators" and are 3 words that increase by each random seed from a simple add.

- Execute the "oscillators" for some time interval

To get the random number each 16-bit oscillator produces a 8-bit byte by adding MSB+LSB.

Calculate the random number as:

((MSB1+LSB1)*(MSB2+LSB2))+(MSB3*256+LSB3)

The result is a 16-bit random number. You can reduce it to 8-bit by adding MSB+LSB.

The code:

Code: Select all

`tab44=$1D00 ; use a page of mem (multiplication)`

start

lda $9119

sta randomseed

lda $9004

sta randomseed+1

cmp $9004

beq *-3

lda $9118

sta randomseed+2

jsr initmult

ldx #$ff

rndlp1 ldy #$ff

rndlp2

jsr randomize

dey

bne rndlp2

dex

bne rndlp1

jsr get16rand

rts

randomize

; "oscillates" 3 different 16-bit numbers based on 3 seeds

lda randomosc

clc

adc randomseed

sta randomosc

lda randomosc+1

adc #0

sta randomosc+1

lda randomosc+2

clc

adc randomseed+1

sta randomosc+2

lda randomosc+3

adc #0

sta randomosc+3

lda randomosc+4

clc

adc randomseed+2

sta randomosc+4

lda randomosc+5

adc #0

sta randomosc+5

rts

get16rand

lda randomosc

clc

adc randomosc+1

tax

lda randomosc+2

adc randomosc+3

tay

jsr mult88f ;Result in $92-$93

lda randomosc+4

clc

adc $92

tax

lda randomosc+5

adc $93

tay

rts ;random number in x & y register

; lower4bits=l4b

; higher4bits=h4b

; utilize x=l4bx+16*h4bx and y=l4by+16*h4by

; x*y=14bx*14by+l4bx*16*h4by+16*h4bx*l4by+16*16*h4bx*h4by

; Multiplication routine for faster multiplication

initmult ; set up 15x15 multiplication table

ldx #$f

im1 ldy #$f

im2 jsr mult44

sta $96

iny

txa

asl

asl

asl

asl

sta im3+1

lda $96

im3 sta tab44,y

dey

bne im2

dex

bne im1

rts

mult44 ; Mike's 4x4 multiplication code

DEY ; 2 To counteract carry add: %1111->%1110 + C

STY $96 ; 3

TXA ; 2

ASL ; 2

ASL ; 2

ASL ; 2

ASL ; 2 %XXXX0000

ASL ; 2 %XXX00000

BCC rm0 ; 3

ADC $96 ; 3 %XXX01111

rm0 ASL ; 2 %XX011110

BCC rm1 ; 3

ADC $96 ; 3 %XX011110+1110+c=%11101101

rm1 ASL ; 2 %X1011010

BCC rm2 ; 3

ADC $96 ; 3 %X1011010+1110+c=%X1101001

rm2 ASL ; 2 %11010010

BCC rm3 ; 3

ADC $96 ; 3 %11010010+1110+c=%11100001=225=15*15

rm3 RTS ; 2

mult88f

txa ;2

and #$f ;2

sta m4s1+1 ;4

asl ;2

asl ;2

asl ;2

asl ;2

sta m4u1+1 ;4

; 20c

txa ;2

and #$f0 ;2

sta m4s2+1 ;4

lsr ;2

lsr ;2

lsr ;2

lsr ;2 (c=0)

sta m4s3+1 ;4

; 20c

tya ;2

and #$f0 ;2 h4by

tax ;2

tya ;2

and #$f ;2 l4by

tay ;2

m4s1 lda tab44,x ;5 l4bx*h4by

m4s2 adc tab44,y ;5 h4bx*l4by - c=0, overflow in carry

; 22c

sta $92 ;3

; and #$f0 ;4 highest bits unnecessary -> lowest bits cleared

ror ;2 shift right and put carry in bit7

lsr ;2

lsr ;2

lsr ;2 all bits in bit4-bit0

sta $93 ;3 high byte result (e.g. *16)

lda $92 ;3

and #$f ;2

asl ;2

asl ;2

asl ;2

asl ;2 *16

; sta $92 ;3 low byte result

m4u1 adc tab44,y ;5 l4bx*l4by

; adc $92 ;3 add low byte, overflow->carry (kept until adc)

sta $92 ;3

lda $93 ;3

m4s3 adc tab44,x ;5 h4bx*h4by*16*16, add overflow carry

;adc $93 ;3 result high byte, add overflow carry

sta $93 ;3

; 108cycles for 8-bit*8-bit multiplication

rts

randomseed

byte 0,0,0

randomosc

word 0,0,0

I am hoping that the 3 "oscillators" will give a very long series of random numbers without repeat. Having 3 seeds also help in not producing the same series, but there is a slight chance that this may happen. Increasing the number of "oscillators" (&seeds) will reduce the chance, but it will not get to zero.

I am not using the VIA's, but they would practically do the same thing. As the code is in assembly, the timing will always be the same (the code runs at the same speed), so only some artificial "oscillator" will work.

For the C64 someone used the noise generator to get random numbers, but I can't see how this could be done on the Vic-20.

For simplicity I put the "randomizer" in a nested loop to run it >65000 times before it gets the random number. In a program (game or whatever) you would simply use "randomizer" as part of the interrupt/game loop.

Any suggestions would be appreciated.