How to create random number with machine code?
How to create random number with machine code?
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
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?
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
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?
Thank you, short and easy
Re: How to create random number with machine code?
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
In basic you can just do :-
POKE 0,PEEK(#308)AND3
and in assembly
lda $0308
and #$03
sta $00
rts
Amateurs built the Ark, Professionals built the Titanic.
Re: How to create random number with machine code?
Thank you too
- NekoNoNiaow
- Flight Lieutenant
- Posts: 272
- Joined: Sun Jan 15, 2006 10:08 pm
- Location: Montreal, Canadia
Re: How to create random number with machine code?
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.
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?
I discovered this online somewhere to give integers upto 255 :-
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.
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.
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
.)
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
lda #>DISPLAY_ADDRESS
sta write+2
ldx #200 ; loop counter
mainloop
jsr getrand ; random number generator
jsr PrDec
jsr addspace ;add spaces between numbers
dex
bne mainloop
rts
write ; write char and advance 1 position
sta $0123
clc ; Calc new scren address
lda write+1
adc #01
sta write+1
lda write+2
adc #0
sta write+2
rts
addspace ;add spaces between numbers
clc
lda write+1
adc #2
sta write+1
lda write+2
adc #0
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
adc #100
jsr PrDecDigit ;\ Print the 100s
ldy #$FF
sec ;\ Prepare for subtraction
PrDec10
iny
sbc #10
bcs PrDec10 ;\ Count how many 10s
adc #10
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
.(
lda #<DISPLAY_ADDRESS
sta write2+1
lda #>DISPLAY_ADDRESS
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
jsr add1 ; advance to next screen position
dex
bne clearloop1
jsr newline ; advance to next line and skip attribute columns
dey
bne clearloop2
rts
write2
sta $0123
rts
add1
clc
lda write2+1
adc #1
sta write2+1
lda write2+2
adc #0
sta write2+2
rts
newline
clc
lda write2+1
adc #2
sta write2+1
lda write2+2
adc #0
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
.)
Hope this helps.
Amateurs built the Ark, Professionals built the Titanic.
Re: How to create random number with machine code?
@Badger: +1!
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.
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?
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...
randseed .word $dead ; will it be $dead again?
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?
I tried to call your method from c but it's look like a répétitive séquence ... :Badger wrote: ↑Fri Feb 01, 2019 10:23 am I discovered this online somewhere to give integers upto 255 :-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.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 .)
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
unsigned char b;
asm("lda %b;"
"beq doEor;"
"asl;"
"beq noEor;"
"bcc noEor;"
"doEor: eor #$1d;"
"noEor: sta %b;");
Code: Select all
// unsigned int randgen();
unsigned i;
unsigned char b;
void main()
{
unsigned adr=0xA000;
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))
{
poke(adr+i,b);
}
}
}
}
}
Re: How to create random number with machine code?
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.
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?
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.
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.
Amateurs built the Ark, Professionals built the Titanic.
Re: How to create random number with machine code?
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:
Which apparently means it cannot discard it is a random sequence (which is quite good).
Also this is the histogram of generated values: And the routine is small and fast...
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
Also this is the histogram of generated values: And the routine is small and fast...