Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What to pass to srand()?

89 views
Skip to first unread message

Matt

unread,
Jan 18, 2014, 3:28:53 AM1/18/14
to
In apple2 C programming how do you get pseudo random integers in a given
range for example 0 - 1295?

On the pc I pass srand() the system time but this doesn't work for
apple2. Calls to rand() come up with the same value repeatedly.

Matt.

Marco Verpelli

unread,
Jan 18, 2014, 4:31:48 AM1/18/14
to
Do you use Aztec C?
If so have a look at the man page: http://www.aztecmuseum.ca/cat1.htm#RAN

Matt

unread,
Jan 18, 2014, 3:22:53 PM1/18/14
to
On 18/01/14 22:31, Marco Verpelli wrote:
> Do you use Aztec C?
> If so have a look at the man page: http://www.aztecmuseum.ca/cat1.htm#RAN
>

Thx Marco. For this project I am using cc65. I will need to look at some
of the example code to find how to do it. That or change everything back
to aztec for randl() then find something else which is easier with cc65
- back and forth forever :-)

Egan Ford

unread,
Jan 18, 2014, 5:24:23 PM1/18/14
to
Do you have any keyboard input before you need a random number? I've
used that in the past. E.g. a loop in assembly that is incrementing a
32-bit value while the user types. Even something as simple as "return
to continue" can be used.

If no keyboard input and if targeting the Apple II you could use the
vertical blank interval.

Bill Buckels

unread,
Jan 18, 2014, 6:32:11 PM1/18/14
to
"Egan Ford" <data...@gmail.com> wrote:
>Do you have any keyboard input before you need a random number?

Why not both a mouse and keboard loop to increment a range counter, then use
a modulus operator on the range counter as an index into a table of expected
valid values if those values are not necessarily sequential?

http://www.appleoldies.ca/MeToo.pdf

See the link above. When I ported my MeToo program from MS-DOS to the Apple
II (source is of course available from the Aztec C Website along with many
other sources) I did that just for fun.

As for the random number generator in Aztec C, here's the source but you
can't port it to cc65 because unlike Aztec C65 which also supports robust
inline assembly, cc65 does not support floating point math. I actually added
this to the Commdore 64 Aztec C65 version for another Aztec C User who
couldn't use cc65 because of its lack of math support:

/*
* Random number generator -
* adapted from the FORTRAN version
* in "Software Manual for the Elementary Functions"
* by W.J. Cody, Jr and William Waite.
*
* http://en.bookfi.org/book/546944
*/

/*

NAME:
ran - random number generator
SYNOPSIS:
double ran()
DESCRIPTION:
ran returns as its value a random number between 0.0 and 1.0

*/



double ran()
{
static long int iy = 100001;

iy *= 125;
iy -= (iy/2796203) * 2796203;
return (double) iy/ 2796203.0;
}

double randl(x)
double x;
{
double exp();

return exp(x*ran());
}


Another approach you could do would be to roll your own random number
generator using the time in the no-slot clock as a seed.

Here's how you use the NSC which is already built into AppleWin:

Available for Download at the Aztec C Website at the following link:

http://www.aztecmuseum.ca/UTL.zip

This zip file contains a number of Apple IIe Utilities written in Aztec C
that run under the ProDOS Aztec C Shell.

Some of these utilites make use of the Apple IIe's No Slot Clock.

Perhaps a simpler NSC example is in the DHRYSTONE benchmark program for
Aztec C:

DHRYSTONE 1.1 for Apple IIe ProDOS 8 Aztec C65 3.2b cross-compiler:

http://www.aztecmuseum.ca/extras/DHRY.zip

Remember too that you can't put lips on a fish.

Bill


Bill Buckels

unread,
Jan 18, 2014, 6:38:11 PM1/18/14
to
"Bill Buckels" <bbuc...@mts.net> wrote:
>Remember too that you can't put lips on a fish.

Oops. Sorry about that. That should have said: "You can't put lips on a
sucker and call it a walleye."

Bill



Michael J. Mahon

unread,
Jan 18, 2014, 7:26:54 PM1/18/14
to
Any time the Apple II is waiting for keyboard input via any built-in
routine, it is incrementing a 16-bit counter on page zero. This is intended
as either a source of 16-bit (or less) random numbers (after a keyboard
input) or as a source to seed a PRNG to provide a long stream of random
numbers.

The same method can be adapted to any other input device.

While you are debugging, it is useful to seed a PRNG with a constant, so
that the computation is repeatable.

When you're ready for unpredictable PRNs, seed with something derived from
an unpredictable event--like how many tens of microseconds it takes a human
to respond to a prompt.

Time to VBL is useful only if some unpredictable time has elapsed since
boot or reset, since the video generator is started synchronously with the
processor and is driven from the same clock. (Of course, any user
interaction will "pause" the running code for an unpredictable time, after
which a "count until VBL" will have an unpredictable result.)

I tried to get an unpredictable value from the machines in an AppleCrate,
all powered on from the same power supply. I could not find any way to get
sufficient nondeterminism.

My later (and more satisfactory) solution is to daisy-chain the machine ID
assignment. This assigns each machine in a 'Crate a unique ID in strictly
ascending order corresponding to the daisy-chain wiring, keeping the IDs
consistent with physical position and consecutive.

This machine ID number can then be used to seed each machine's RND function
uniquely when desired.
--
-michael - NadaNet 3.1 and AppleCrate II: http://home.comcast.net/~mjmahon

gid...@sasktel.net

unread,
Jan 19, 2014, 12:17:03 AM1/19/14
to
Although your number selection is quite large, this might give you some ideas. This is what I do for a deck of cards. The cards get assigned values 11 to 1D for spades, 21 to 2D for hearts, 31 to 3D for diamonds and 41 to 4D for clubs. I use the the apple II random number generator at $EFAE. $C9 to $CE holds the random number but $CC has been calculated to be the most evenly random, with the random numbers being more average (no one number is chosen more so over the others). The random # in $CC is just used to pick two cards and swap them.

When playing the cards, they can be either saved backed to memory as they are played, or you can randomly shuffle the previous random deck. Either way, the cards were random to begin with, so it does not matter if the random number generator is perfect. The card deck being random and getting a random sequence that repeats, will still result in a very random deck. The deck of cards now becomes you random # generator. If you play the random deck in sequence, this also has the added benefit of no two numbers being selected twice until the whole deck has been played.

Rob

Michael J. Mahon

unread,
Jan 19, 2014, 12:15:19 PM1/19/14
to
Of course, viewed as a sequence, this is a deviation from "random". Using
the "deck" is drawing from an urn without replacement, while most
simulations, etc., assume drawing *with* replacement.

For example, each throw of a die is independent of history, so all values
are equally likely. This requires drawing with replacement.

Dealing cards, though, unless done from an infinite number of decks, is
always without replacement.

Egan Ford

unread,
Jan 19, 2014, 4:33:04 PM1/19/14
to
On 1/18/14, 5:26 PM, Michael J. Mahon wrote:
> Time to VBL is useful only if some unpredictable time has elapsed since
> boot or reset, since the video generator is started synchronously with the
> processor and is driven from the same clock. (Of course, any user
> interaction will "pause" the running code for an unpredictable time, after
> which a "count until VBL" will have an unpredictable result.)

Is that also the case when booting from disk and running a program from
disk. Or is the disk I/O that predictable.

Vladimir Ivanov

unread,
Jan 19, 2014, 6:35:54 PM1/19/14
to


On Sat, 18 Jan 2014, Michael J. Mahon wrote:

> I tried to get an unpredictable value from the machines in an AppleCrate,
> all powered on from the same power supply. I could not find any way to get
> sufficient nondeterminism.

That reminds me of my kid attempts to get random values - by reading the
floating bus. Only that back then I didn't know it was mirroring the video
scanner and they seemed random(-ish) to me.

Here is a short lo-res maze generator, deriving "randomness" from bits off
the floating bus. Silly, but that part of the hardware wasn't explained in
the few local books I had read. Even sillier, given the maze generating
algorithm, it works, even if there is no entropy at all.

That was maybe my first serious attempt to translate BASIC program to
machine language.



maze.dsk.gz

gid...@sasktel.net

unread,
Jan 20, 2014, 12:19:39 AM1/20/14
to

> Dealing cards, though, unless done from an infinite number of decks, is
> always without replacement.


I was not referring to dealing.

Consider this. Everyone knows the card trick when you take a card, look at it and put it back. This is with replacement.

You still can pick a random card from a random deck, then it won't matter how random the generator is. Shuffle the deck using an imperfect random # generator, and pick a random card using the imperfect generator. It won't matter if the sequence repeats because the cards at those locations will have been changed, making the outcome pretty random.

As in real life, I don't believe the die should be equally likely either. To me this is not random either. It is more like controlling the laws of averages, so each die has an equal chance of showing each number, which is what we humans want from a perfect world. If this were true and each number had an equal chance of showing up, I would have won Lotto 6/49 a long time ago. My lucky numbers sure are not being given an equal chance.

Michael J. Mahon

unread,
Jan 20, 2014, 12:27:11 AM1/20/14
to
Good point!

If power is applied with a bootable disk installed, the initial rotational
position of the disk is indeterminate, so at least the latency of the first
read is a random variable. For a 5.25" disk, that's 300ms of variation.
Since VBL occurs every 17ms, time to VBL should be uniformly distributed.

In addition, drive speed variation is a further source of nondeterminacy.

So, yes--the initial disk read randomizes the processor-to-video generator
timing nicely.

Again, if a program is run manually by typing, or if any other interaction
occurs prior to timing to VBL, then the input wait will be enough to
randomize the timing.

Michael J. Mahon

unread,
Jan 20, 2014, 1:14:49 AM1/20/14
to
Sure they are.

Each combination of six numbers from 1 to 49, without replacement, has one
chance in:
49x48x47x46x45x44 / 6x5x4x3x2x1
of being generated.

That evaluates to one chance in 13983816.
So you have to play about a million times to have even a 7% chance of
winning.

That's why mathematicians seldom play the lottery. ;-)

Unless you have reason to believe the "ball machine" is broken, the numbers
selected are random. Ditto for any fair die or coin, etc.

By the way, combining multiple poor PRNGs does not make a good PRNG. this
is nicely (even humorously) covered in Knuth volume 2, IIRC.

A good PRNG does not come from a complicated, hard to understand algorithm.
Instead, a quality PRNG is simple, with easily understood mathematical
behavior--just well-distributed results that are nearly indistinguishable
from a sequence of *actual* random numbers when subjected to a battery of
tests.

Incidentally, the Applesoft RND generator is quite poor, entering a short
cycle after several thousand calls. Further, an off-by-one bug in the
Applesoft initialization code causes only four bytes of its five-byte seed
to be set!
0 new messages