Page 1 of 1

RND function

Posted: Mon Dec 06, 2010 8:46 pm
by carlsson
In my further studies of the Creativision Basic, I have come to the RND function. Barry Klein once wrote in the second Wizzdom newsletter:
1982 BASIC: RND(N) gives results in the range 0 to N-1
1983 BASIC: RND(N) gives results in the range 1 to N

For a random number in the range 0 to N-1, use RND(N)-RND(1)
For a random number in the range 1 to N, use RND(N)-RND(1)+1

Array elements and functions don't work properly as array subscripts, e.g. A(RND(3)) always gives A(3).
This must be separated into two statements: X=RND(3) then use A(X).
At this point, I tried Barry's own speed hacked Basic and made a terrible discovery: it runs so fast (!) that the random number generator is only regenerated once every time you run the program. Take for example this program:

10 FORI=1TO10
20 PRINTRND(5);
30 NEXT

It can be pointed out that the 1982 BASIC mentioned in the Wizzdom equals 1982 R1. The other version marked 1982 R2 has the same RND behavior as the 1983 releases.

Re: RND function

Posted: Tue Dec 07, 2010 10:06 am
by carlsson
Speaking of the RND function, this is the kind of program I was trying to write yesterday. It is a DOG SLOW side scroller.. well, right now it is just a field of stars scrolling from right to left, but the playfield is 40 columns wide while only 28 columns are displayed simultaneously.

Code: Select all

5 CLS
10 DIMH(40)
11 FORI=1TO40
12 H(I)=RND(5)-RND(1)+1
13 NEXTI
14 A$="                            "
15 B$=A$
16 C$=A$
17 D$=A$
18 E$=A$
19 I=1
20 J=5
21 GOSUB100
22 A$=RIGHT$(A$,27)+X$
24 GOSUB100
25 B$=RIGHT$(B$,27)+X$
27 GOSUB100
28 C$=RIGHT$(C$,27)+X$
30 GOSUB100
31 D$=RIGHT$(D$,27)+X$
33 GOSUB100
34 E$=RIGHT$(E$,27)+X$
41 POKE218,2
42 POKE219,208
43 PRINTA$
44 PRINTB$
45 PRINTC$
46 PRINTD$
47 PRINTE$
48 I=I+1
49 IFI>40THENI=1
50 GOTO 20
100 X$=" "
105 IFH(I)>=JTHENX$="*"
107 J=J-1
110 RETURN
Apart from running it in Barry's speed hacked Basic which doesn't seem to handle RND like expected, I'm not yet sure which improvements could be made. I regret that strings may not be kept in arrays, even if it would not make any difference on execution speed.

I tried to use PEEK(3) instead of RND but it behaves in the same way re. speeded Basic.

Update 2: Here is an improved listing, which also may run a little fast as I found a way to use the SGN function. It runs in 1983 Basic, haven't tried the 1982 R1 Basic.

Code: Select all

1 L=60
2 DIMH(L)
3 V=1
4 FORI=1TOL
5 R=RND(3)-RND(1)+1
6 IFR=1ANDV>1THENV=V-1
7 IFR=3ANDV<5THENV=V+1
8 H(I)=V
9 NEXTI
10 A$="                            "
11 B$=A$
12 C$=A$
13 D$=A$
14 E$=A$
15 X$=" *"
16 I=1
19 CLS
20 A$=RIGHT$(A$,27)+MID$(X$,1+SGN(H(I)>=5),1)
21 B$=RIGHT$(B$,27)+MID$(X$,1+SGN(H(I)>=4),1)
23 C$=RIGHT$(C$,27)+MID$(X$,1+SGN(H(I)>=3),1)
24 D$=RIGHT$(D$,27)+MID$(X$,1+SGN(H(I)>=2),1)
25 E$=RIGHT$(E$,27)+MID$(X$,1+SGN(H(I)>=1),1)
30 POKE218,2
31 POKE219,210
32 PRINTA$
33 PRINTB$
34 PRINTC$
35 PRINTD$
36 PRINTE$
37 I=I+1
38 IFI>LTHENI=1
39 GOTO 20

Re: RND function

Posted: Sun Sep 18, 2011 8:39 am
by MADrigal
About Barry Klein's speed hack. As far as I remember, it's not a matter of "it running so fast -> the random generator works once per run". Ithink the speed hack also consists in "ignoring" the random generator. Not sure about that, but I think that Berry explained what actually changed with his speed Basic, and it had to do with the RND function.

Re: RND function

Posted: Mon Feb 04, 2013 10:01 pm
by carlsson
For what it is worth, the BIOS routine at $FF58 seems to output decent pseudo-random numbers, except that all numbers are even. Note that it can't be used directly from BASIC anyway, as there is no CALL function and the result ends up in the accumulator anyway, but for machine code programs JSR $FF58 will pretty much generate numbers between $00 and $FF.

Re: RND function

Posted: Sat May 11, 2013 8:04 am
by Mobsie
Hi Carlsson,
have you test the BIOS RND function in assembler because i need a RND function?
And when the BIOS function work okay why not use.
thank you

Re: RND function

Posted: Sun May 12, 2013 2:52 pm
by carlsson
Yes, in Reversi I call $FF58. The value is returned in A and seems fairly OK, except that you only get even numbers.

Code: Select all

PHA
JSR $FF58
TAX
PLA
CPX #77 ; 30% of maximum value
BCS ...

Re: RND function

Posted: Tue Apr 25, 2023 11:05 am
by Mobsie
Hi,

i try to use this one:

; Returns a random 8-bit number in A (0-255), clobbers Y (unknown).
prng:
lda seed+1
tay ; store copy of high byte
; compute seed+1 ($39>>1 = %11100)
lsr ; shift to consume zeroes on left...
lsr
lsr
sta seed+1 ; now recreate the remaining bits in reverse order... %111
lsr
eor seed+1
lsr
eor seed+1
eor seed+0 ; recombine with original low byte
sta seed+1
; compute seed+0 ($39 = %111001)
tya ; original high byte
sta seed+0
asl
eor seed+0
asl
eor seed+0
asl
asl
asl
eor seed+0
sta seed+0
rts

With the 16 Bit seed the sequence of numbers it generates will repeat after 65535 calls. That’s great.

Also the bios rnd function only deliver one random number in one frame, maybe i do wrong but also $03 only one per frame.

But i need more to init the enemy’s , and here this should not an issue.

Re: RND function

Posted: Tue Apr 25, 2023 4:56 pm
by @username@
That looks like galois16 - the others are here https://github.com/bbbradsmith/prng_6502

Re: RND function

Posted: Tue Apr 25, 2023 6:38 pm
by Mobsie
👍 great