# 2024-05-19 The barely documented CoCo BASIC RND function

In the Tandy Color Computer "Getting Started with Color BASIC" manual states that RND:

Returns a random integer between 1 and the number you specify.

This is a gross simplification.

Looking at the assembly in the Color BASIC Unravelled book, at offset &HBF1F, we see that there are three main paths through RND based on the numeric argument, with values between zero and two being a special fourth unexpected case. Given R=RND(A):

• if A == 0: returns (0 <= R < 1)
• if 0 < A < 2: returns (1).
• if A >= 2: returns INT(0 < R <= INT(A))
• if A < 0: sets the seed based on A, and returns (0 < R < 1)

RND implements a pseudo-random number generator based on a seed, and every time BASIC is initialised, it will generate the same series:

PRINT RND(0)
.498278379


Or, say:

FOR I = 1 TO 10:PRINT RND(10):NEXT I
5
4
2
7
5
4
6
3
2
9


A typical way of seeding the generator is to run RND(-TIMER) once at the start of a program, given that humans are likely to take a random amount of time entering LOAD and RUN.

### Implementation

Variables and constants:

• RVSEED: copied from ROM at &HA132 to &H0115, initial value is &H804FC75259 == 0.811635157. Overwritten each time RND is called.
• RSEED: constant in ROM at &HBF74, value &H40E6, &H4DAB.
• added constant in ROM code &H658B.

I was going to try to write a pseudo-code copy of RND, but given it operates directly on floating-point numbers, and uses eg. ADCB followed by ADCA, it doesn't translate nicely - the cleanest code is the assembly implementation itself. Squinting, it seems to be a form of linear congruential generator, although deals with floats and throws in some additional mixing before returning.