OSDK & Random numbers
- coco.oric
- Squad Leader
- Posts: 720
- Joined: Tue Aug 11, 2009 9:50 am
- Location: North of France
- Contact:
OSDK & Random numbers
Hi,
I've looked on all topics in the CEOMAGs about randomize numbers.
The same on the forums of Defence Force.
I'm looking to write a new document on random numbers in the next CEOMAG (and i've only 8 days left to write it), and writing some routines for my "future" software.
Some questions :
- In C with OSDK, i've tested RAND(). It's ok. But it don't undersand how to change the SEED (normally with SRAND but it seems not work (with #included lib.h)).
- do you have write some routines which are not on the forum yet
Thanks a lot, Didier
I've looked on all topics in the CEOMAGs about randomize numbers.
The same on the forums of Defence Force.
I'm looking to write a new document on random numbers in the next CEOMAG (and i've only 8 days left to write it), and writing some routines for my "future" software.
Some questions :
- In C with OSDK, i've tested RAND(). It's ok. But it don't undersand how to change the SEED (normally with SRAND but it seems not work (with #included lib.h)).
- do you have write some routines which are not on the forum yet
Thanks a lot, Didier
coco.oric as DidierV, CEO Member
Historic owner of Oric, Apple II, Atari ST, Amiga
Historic owner of Oric, Apple II, Atari ST, Amiga
Maybe not the best random routine around, but this is the one from Elite, and I am using it in 1337...
It uses a 6 byte seed for galaxy creation and a 4 byte rnd_seed for random number generation. The init_seed copies the base seed for galaxy (which can be ommited if you only want the generator) and uses the last four bytes of this to initialize the rnd_seed (thus $0248 and $b753).
The _gen_rnd_number routine (which could be called in C as int gen_rnd_number() ), returns a 16-bit result (regs A and X) and also alters the other two bytes, so a 4-byte random number is generated.
It uses a 6 byte seed for galaxy creation and a 4 byte rnd_seed for random number generation. The init_seed copies the base seed for galaxy (which can be ommited if you only want the generator) and uses the last four bytes of this to initialize the rnd_seed (thus $0248 and $b753).
The _gen_rnd_number routine (which could be called in C as int gen_rnd_number() ), returns a 16-bit result (regs A and X) and also alters the other two bytes, so a 4-byte random number is generated.
Code: Select all
_seed .dsb 6
_rnd_seed .dsb 4
;unsigned int base0=0x5A4A;
;unsigned int base1=0x0248;
;unsigned int base2=0xB753; /* Base seed for galaxy 1 */
_base0 .word $5a4a
_base1 .word $0248
_base2 .word $b753
;; Elite random function
;; Initialize seeds for galaxy 1
_init_rand
.(
ldx #5
loop
lda _base0,x
sta _seed,x
dex
bpl loop
ldx #3
loop2
lda _seed+2,x
sta _rnd_seed,x
dex
bpl loop2
rts
.)
; This is inspired in the reverse engineered
; source of eliteagb
_gen_rnd_number
.(
;int A = (g_rand_seed.r0*2)|(*carry!=0);
;int X = A&0xff;
;A = (X + g_rand_seed.r2 + (A>0xff)); // carry from this used below
;g_rand_seed.r0 = A;
lda _rnd_seed
rol ; It is commented that this is the exact code in original Elite, and not asl
tax
adc _rnd_seed+2
sta _rnd_seed
;g_rand_seed.r2 = X;
txa
sta _rnd_seed+2
;A = (g_rand_seed.r1 + g_rand_seed.r3 + (A>0xff));
;*carry = (A>0xff);
;A&=0xff;
lda _rnd_seed+1
clc
adc _rnd_seed+3
;X = g_rand_seed.r1;
ldx _rnd_seed+1
;g_rand_seed.r1 = A;
;g_rand_seed.r3 = X;
sta _rnd_seed+1
stx _rnd_seed+3
;return A;
rts
.)
Here is the one I'm using in 4kkong, not sure where I got it from:
Code: Select all
;// Some one byte temporaries
rand_low .dsb 1 ;// Random number generator, low part
rand_high .dsb 1 ;// Random number generator, high part
;// Calculate some RANDOM values
;// Not accurate at all, but who cares ?
;// For what I need it's enough.
_GetRand
lda rand_high
sta b_tmp1
lda rand_low
asl
rol b_tmp1
asl
rol b_tmp1
asl
rol b_tmp1
asl
rol b_tmp1
clc
adc rand_low
pha
lda b_tmp1
adc rand_high
sta rand_high
pla
adc #$11
sta rand_low
lda rand_high
adc #$36
sta rand_high
rts
Just noticed that I am doing:
I supposed I modified something, as this could be optimized to
Code: Select all
;g_rand_seed.r2 = X;
txa
sta _rnd_seed+2
;A = (g_rand_seed.r1 + g_rand_seed.r3 + (A>0xff));
;*carry = (A>0xff);
;A&=0xff;
lda _rnd_seed+1
Code: Select all
;g_rand_seed.r2 = X;
stx _rnd_seed+2
;A = (g_rand_seed.r1 + g_rand_seed.r3 + (A>0xff));
;*carry = (A>0xff);
;A&=0xff;
lda _rnd_seed+1
- coco.oric
- Squad Leader
- Posts: 720
- Joined: Tue Aug 11, 2009 9:50 am
- Location: North of France
- Contact:
Thanks a lot for your routines.
4KKong routine is ok. i've found the mathematical theorie which is associated.
For elite remake, If i understand well your routine, only seed+1 and seed+3 are used to create the random number on A at the end of the routine.
It's a "fibonacci suite". I'll test the quality of the random within a few days for the mag.
the seed values at +0 and +2 seems to be used to a similar calculation but i don't find the mathematical reason of the rol instruction.
searching now for another type of fibonacci suite.
4KKong routine is ok. i've found the mathematical theorie which is associated.
For elite remake, If i understand well your routine, only seed+1 and seed+3 are used to create the random number on A at the end of the routine.
It's a "fibonacci suite". I'll test the quality of the random within a few days for the mag.
the seed values at +0 and +2 seems to be used to a similar calculation but i don't find the mathematical reason of the rol instruction.
searching now for another type of fibonacci suite.
coco.oric as DidierV, CEO Member
Historic owner of Oric, Apple II, Atari ST, Amiga
Historic owner of Oric, Apple II, Atari ST, Amiga
Yep the generator is a fibonacci sequence (I think). The four bytes are used around the code, although for a C interface only two are returned, the other two could be seen as global.
It was reverse-engeneered, as I stated, so no idea about internal details.
I found another routine a friend of mine wrote years ago. Not sure about its origin, but I have the original comments on it, which are also quite fun to read.
Anyway I tried to make it compatible with XA and here is the code:
For what he says on the comments it is 43 cycles only, and you can see it is intended to be used with asm (add a ldx randseed to make it usable from C).
No idea about its performance, but for some comments of the author:
Cheers
It was reverse-engeneered, as I stated, so no idea about internal details.
I found another routine a friend of mine wrote years ago. Not sure about its origin, but I have the original comments on it, which are also quite fun to read.
Anyway I tried to make it compatible with XA and here is the code:
Code: Select all
_randgen
php ; INTERRUPTS MUST BE ENABLED! We store the state of flags.
cli
lda randseed ; get old lsb of seed.
ora $3e8 ; lsb of VIA T2L-L/T2C-L.
rol ; this is even, but the carry fixes this.
adc $3e4 ; 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.
plp
rts ; see you later alligator.
randseed
.word $dead ; will it be $dead again?
No idea about its performance, but for some comments of the author:
Code: Select all
;;; The biggest unanswered question is: *how random is it?* Well, pretty much, in my opinion. I generated 14000 instances of
;;; semi-random words and tried these tests:
;;; (i) Is the output compressible?
;;; No. At least, gzip cannot compress the sequence. This is a fair indication of lack of patterns.
;;; (ii) Is the output easily reproducible?
;;; Well, it is in theory, but that would need (I think) hardware reset and exquisite timing, and I have not a
;;; clue of how to reproduce a particular sequence.
;;; (iii) Is statistically uniform?
;;; I haven't tested this thoroughly enough. But so it seems.
;;; (iv) Given a particular seed and a finite number of elements of a sequence, can one deduce the next element?
;;; Not in your life. To prove it, try to code this in C. You won't succeed, guess why...
- coco.oric
- Squad Leader
- Posts: 720
- Joined: Tue Aug 11, 2009 9:50 am
- Location: North of France
- Contact:
thanks a lot for this other solution.
i'll make some researches.
for elite, if my calculation is good
- rnd_seed +1 = $48
- rnd_seed +3 = $53
the histogram of datas for 65000 calculations ... is not very random !
[/img]
i'll make some researches.
for elite, if my calculation is good
- rnd_seed +1 = $48
- rnd_seed +3 = $53
the histogram of datas for 65000 calculations ... is not very random !
[/img]
coco.oric as DidierV, CEO Member
Historic owner of Oric, Apple II, Atari ST, Amiga
Historic owner of Oric, Apple II, Atari ST, Amiga
Well, I know the generator for Elite is not very random at all... It is used to create the galaxy and all the universe
However I am sure that some bits of the four random seeds are used for random events. I was tempted to include another random generator for that purpose, but I am not sure if it is necessary. Testing a single bit or if a value is below or above a certain threshold for deciding a type of ship or its equipment should not need true random numbers...
As once Dbug said (IIRC) in addition it is good to have a pseudo generator which would repeat the same sequence for each run, to test the program...
mmm now that I think about it, maybe it was not a good idea to confuse you with this routine, when it is not intended (in fact) to generate random numbers, but a known sequence... if that is the case, I am sorry.
However I am sure that some bits of the four random seeds are used for random events. I was tempted to include another random generator for that purpose, but I am not sure if it is necessary. Testing a single bit or if a value is below or above a certain threshold for deciding a type of ship or its equipment should not need true random numbers...
As once Dbug said (IIRC) in addition it is good to have a pseudo generator which would repeat the same sequence for each run, to test the program...
mmm now that I think about it, maybe it was not a good idea to confuse you with this routine, when it is not intended (in fact) to generate random numbers, but a known sequence... if that is the case, I am sorry.
It's really always a question of what you want to use the random generator for.
For debugging and testing purpose it's nice to be able to reproduce an exact sequence of events just by storing a seed.
This VIA based random generator is interesting If one don't really care about the reproducibility but only want long series of numbers who don't loop, it looks like a good idea.
For debugging and testing purpose it's nice to be able to reproduce an exact sequence of events just by storing a seed.
This VIA based random generator is interesting If one don't really care about the reproducibility but only want long series of numbers who don't loop, it looks like a good idea.
- coco.oric
- Squad Leader
- Posts: 720
- Joined: Tue Aug 11, 2009 9:50 am
- Location: North of France
- Contact:
Thanks a lot for your contribution, i've finished a compilation about random for next ceo-mag.
It's also a big help for my low low low return to the 80's.
My next research will be about making .DSK with OSDK and other tools.
I'll made a post when i'll get some questions for you people expert on oric.
After this study on random, i'll make the routines to create the basics of my ORIC TALE (in honor to Bard's Tale)
Didier
It's also a big help for my low low low return to the 80's.
My next research will be about making .DSK with OSDK and other tools.
I'll made a post when i'll get some questions for you people expert on oric.
After this study on random, i'll make the routines to create the basics of my ORIC TALE (in honor to Bard's Tale)
Didier
coco.oric as DidierV, CEO Member
Historic owner of Oric, Apple II, Atari ST, Amiga
Historic owner of Oric, Apple II, Atari ST, Amiga