Page 1 of 1

### How to create random number with machine code?

Posted: Sun Dec 23, 2018 12:45 am
Can you help me how to create a random number with machine code?

I need 4 different cases when I call the routine. So what ı want is ;

For example.. As basic commands
CALL x
P=PEEK(0)

So, P will get 0,1,2 or 3 randomly from memory adress 0

To explain it briefly Its like P=INT (4*RND(0))

Thanks

### Re: How to create random number with machine code?

Posted: Sun Dec 23, 2018 7:11 am
Short reply (sorry, in a hurry): I would read the timer's low byte and keep the 2 lower bits from it.

Something like
LDA \$0308
then any other instruction to set the 6 bits to 0, giving 000000xy
(than would probably be AND #\$03 but please double check, I have to leave now )

then A = 0, 1, 2 or 3.
Store it in \$00 with
STA \$00

and don't forget to end the program with
RTS

### Re: How to create random number with machine code?

Posted: Sun Dec 23, 2018 9:52 am
Thank you, short and easy

### Re: How to create random number with machine code?

Posted: Sun Dec 23, 2018 10:05 am
I can confirm Symoon's answer is correct.

In basic you can just do :-
POKE 0,PEEK(#308)AND3

and in assembly

lda \$0308
and #\$03
sta \$00
rts

### Re: How to create random number with machine code?

Posted: Sun Dec 23, 2018 10:50 am
Thank you too

### Re: How to create random number with machine code?

Posted: Fri Feb 01, 2019 5:53 am
How are you using the generated random numbers?
I ask because if you are generating them inside a loop there is a high chance that they will repeat if the timing of the loop is more or less constant. What I would recommend actually is to use a simple modulo based random generator (*) and initialize it using the number read from the timer.

(*) here is a simple enough one that gives very acceptable results for a relatively good performance (if you use a multiplication table): https://en.m.wikipedia.org/wiki/Lehmer_ ... _generator.
There was a very good article about random number generation in STMag back in the day which implemented that type of particular generator. If someone recalls which issue that was then please mention it, as it is probably very simple to adapt to the Oric.

### Re: How to create random number with machine code?

Posted: Fri Feb 01, 2019 10:23 am
I discovered this online somewhere to give integers upto 255 :-

Code: Select all

``````getrand
.(
lda \$01
beq doEor
asl
beq noEor ;if the input was \$80, skip the EOR
bcc noEor
doEor
eor #\$1d
noEor
sta \$01
rts
.)``````
All you need to do is seed \$01 with any number at the start or again later with something like the value of the timer after a keypress.
I put together the below to show this. It waits for a keypress and seeds the random number generator (shown above) with the timer value. Prints the seed on the status line, then prints 200 random numbers to the main part of the screen.

Code: Select all

``````#define STATUS_LINE (\$BB80+2)		;first char of status line ignoring attribute chars
#define DISPLAY_ADDRESS (\$BB82+40) 	;first char of non-status line ignoring attribute columns
#define RANDLOC \$01  			;memory location of random number - change as you like
.text
main
.(
jsr clrscreen			;clears the screen

nokey					;check for any keypress
lda \$208
cmp #56
beq nokey

setseed
lda #<STATUS_LINE		;set up memory to print seed on status line
sta write+1
lda #>STATUS_LINE
sta write+2
jsr gettimer 			;seed random generator with current value of timer 1
lda RANDLOC
jsr PrDec			;Print value of random number seeded to screen

lda #<DISPLAY_ADDRESS		;set up memory of 1st character to display random numbers
sta write+1
sta write+2
ldx #200 			; loop counter
mainloop
jsr getrand			; random number generator
jsr PrDec
dex
bne mainloop
rts

write				; write char and advance 1 position
sta \$0123
clc			; Calc new scren address
lda write+1
sta write+1
lda write+2
sta write+2
rts

clc
lda write+1
sta write+1
lda write+2
sta write+2
rts

PrDec						; routine to print out decimals to screen
ldy #\$FF
sec
PrDec100
iny
sbc #100
bcs PrDec100  				;\ Count how many 100s
jsr PrDecDigit    			;\ Print the 100s
ldy #\$FF
sec               			;\ Prepare for subtraction
PrDec10
iny
sbc #10
bcs PrDec10    				;\ Count how many 10s
jsr PrDecDigit     			;\ Print the 10s
tay	                        	;\ Pass 1s into X
PrDecDigit
pha
tya			                ;\ Save A, pass digit to A
ora #\$30
jsr write
pla
rts

.)

gettimer			;get current value of timer 1
.(
lda \$304
sta RANDLOC			; store as seed for random number generator
.)

clrscreen			; clears text screen
.(
sta write2+1
sta write2+2

ldy #27			;row to loop
clearloop2
ldx #38			;cols to loop
clearloop1
lda #32			;ASCII of char to write to screen
jsr write2
dex
bne clearloop1
jsr newline		; advance to next line and skip attribute columns
dey
bne clearloop2
rts

write2
sta \$0123
rts
clc
lda write2+1
sta write2+1
lda write2+2
sta write2+2
rts

newline
clc
lda write2+1
sta write2+1
lda write2+2
sta write2+2
rts

.)

getrand				; random number generator
.(
lda RANDLOC			;loads A with last value of random generator (either the seed or last random)
beq doEor
asl
beq noEor 			;if the input was \$80, skip the EOR
bcc noEor
doEor
eor #\$1d
noEor
sta RANDLOC
rts
.)``````
As an aside to this, I've found that the PrDec routine to the status line is ideal for watching the values of memory or registers without using the monitor or over-writing anything on the main screen.

Hope this helps.

### Re: How to create random number with machine code?

Posted: Fri Feb 01, 2019 11:08 am
IMO this is the best way to produce random numbers too: keypress+timer+algo.
I'm using the same algorithm and the original comes from HERE.

### Re: How to create random number with machine code?

Posted: Fri Feb 01, 2019 4:20 pm
This is the routine I use in my games. I remember I tested its randomness and it was quite good!

Code: Select all

``````; A real random generator...
randgen
.(
lda randseed     	; get old lsb of seed.
ora \$308		; lsb of VIA T2L-L/T2C-L.
rol			; this is even, but the carry fixes this.
adc \$304		; lsb of VIA TK-L/T1C-L.  This is taken mod 256.
sta randseed     	; random enough yet.
sbc randseed+1   	; minus the hsb of seed...
rol			; same comment than before.  Carry is fairly random.
sta randseed+1   	; we are set.
rts			; see you later alligator.
.)``````

### Re: How to create random number with machine code?

Posted: Thu Mar 07, 2019 2:57 pm
Fri Feb 01, 2019 10:23 am
I discovered this online somewhere to give integers upto 255 :-

Code: Select all

``````getrand
.(
lda \$01
beq doEor
asl
beq noEor ;if the input was \$80, skip the EOR
bcc noEor
doEor
eor #\$1d
noEor
sta \$01
rts
.)``````
All you need to do is seed \$01 with any number at the start or again later with something like the value of the timer after a keypress.
I put together the below to show this. It waits for a keypress and seeds the random number generator (shown above) with the timer value. Prints the seed on the status line, then prints 200 random numbers to the main part of the screen.
I tried to call your method from c but it's look like a répétitive séquence ... :

Code: Select all

``````unsigned char b;
asm("lda %b;"
"beq doEor;"
"asl;"
"beq noEor;"
"bcc noEor;"
"doEor:    eor #\$1d;"
"noEor:  sta %b;");``````
with this following program we can see the repetitive sequence (graphics):

Code: Select all

``````// unsigned int randgen();

unsigned i;
unsigned char b;

void main()
{

b=65;
hires();
//cls();
for (i=0;i<8000;i++)
{

asm("lda %b;"
"beq doEor;"
"asl;"
"beq noEor;"
"bcc noEor;"
"doEor:    eor #\$1d;"
"noEor:  sta %b;");

//printf("b=%d \n",b);
if ((b>0)&&(b<128))
{
if ((b>7)&&(b<16))
{
}
else
{
if ((b<24)||(b>31))
{

}
}
}
}

}
``````

### Re: How to create random number with machine code?

Posted: Thu Mar 07, 2019 5:43 pm
Well spotted, goyo!
This algo actually generates chains with period of 256 and "will cycle through the values \$00-\$ff exactly once, in a scrambled order". I.e it's like doing "shuffle" but with 256 cards . I recall that I've used this code because it was small and I needed only numbers in range 0..3, so I've used only 2 low bits.

For a "more real" random generator why not use the OSDK's one but see the Dbug's note here.

### Re: How to create random number with machine code?

Posted: Thu Mar 07, 2019 7:04 pm
Yes Goyo, there is a trade off between small fast code and randomness and if the seed isnt altered then it will be repetetive.

In a game with lots of keypresses you could just re-seed the routine with the value of the timer (\$304) on each keypress which would probably make it as close to random as possible.

I guess, it all depends on what you need and how random you need it to be. In a card game for instance you might actually not want repeating numbers when you shuffle the pack.

### Re: How to create random number with machine code?

Posted: Thu Mar 07, 2019 8:54 pm
Just for the records. The routine I posted before (made by a friend of mine) produces a repeatable series of numbers between 0 and 32768 (repeatable if the seed is re-used, that is), with quite nice randomness properties. Matlab's randomness test shows:

Code: Select all

``````[h,p]=runstest(v, median(v))
Warning: X values exactly equal to V are omitted.
> In runstest (line 167)
h =
0
p =
0.8864``````
Which apparently means it cannot discard it is a random sequence (which is quite good).

Also this is the histogram of generated values:
hist.png (7.3 KiB) Viewed 4940 times
And the routine is small and fast...