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

From Wikistix

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.

See Also