Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.sys.apple2.programmer > #2386 > unrolled thread

Streamlining Applesoft - Random number generators

Started bygids.rs@sasktel.net
First post2016-02-28 21:02 -0800
Last post2018-10-01 07:27 -0700
Articles 20 on this page of 45 — 16 participants

Back to article view | Back to comp.sys.apple2.programmer


Contents

  Streamlining Applesoft - Random number generators gids.rs@sasktel.net - 2016-02-28 21:02 -0800
    Re: Streamlining Applesoft - Random number generators qkumba <peter.ferrie@gmail.com> - 2016-02-29 09:05 -0800
    Re: Streamlining Applesoft - Random number generators wssimms@gmail.com - 2016-02-29 09:07 -0800
      Re: Streamlining Applesoft - Random number generators Michael Pohoreski <michael.pohoreski@gmail.com> - 2016-02-29 12:57 -0800
      Re: Streamlining Applesoft - Random number generators "Michael J. Mahon" <mjmahon@aol.com> - 2016-02-29 17:50 -0800
    Re: Streamlining Applesoft - Random number generators Michael Barry <barrym95838@yahoo.com> - 2016-02-29 17:44 -0800
      Re: Streamlining Applesoft - Random number generators gids.rs@sasktel.net - 2016-02-29 18:38 -0800
      Re: Streamlining Applesoft - Random number generators "Michael J. Mahon" <mjmahon@aol.com> - 2016-02-29 18:46 -0800
      Re: Streamlining Applesoft - Random number generators wssimms@gmail.com - 2016-02-29 18:53 -0800
        Re: Streamlining Applesoft - Random number generators Michael Barry <barrym95838@yahoo.com> - 2016-03-01 00:11 -0800
          Re: Streamlining Applesoft - Random number generators wssimms@gmail.com - 2016-03-01 05:17 -0800
          Re: Streamlining Applesoft - Random number generators Michael J. Mahon <mjmahon@aol.com> - 2016-03-01 10:38 -0600
            Re: Streamlining Applesoft - Random number generators qkumba <peter.ferrie@gmail.com> - 2016-03-01 11:56 -0800
              Re: Streamlining Applesoft - Random number generators Michael Pohoreski <michael.pohoreski@gmail.com> - 2016-03-01 12:13 -0800
              Re: Streamlining Applesoft - Random number generators Michael J. Mahon <mjmahon@aol.com> - 2016-03-01 15:32 -0600
                Re: Streamlining Applesoft - Random number generators qkumba <peter.ferrie@gmail.com> - 2016-03-01 22:47 -0800
            Re: Streamlining Applesoft - Random number generators Michael J. Mahon <mjmahon@aol.com> - 2016-03-01 17:28 -0600
              Re: Streamlining Applesoft - Random number generators Michael Pohoreski <michael.pohoreski@gmail.com> - 2016-03-01 18:50 -0800
                Re: Streamlining Applesoft - Random number generators "Michael J. Mahon" <mjmahon@aol.com> - 2016-03-01 19:25 -0800
                  Re: Streamlining Applesoft - Random number generators gids.rs@sasktel.net - 2016-03-01 22:03 -0800
                    Re: Streamlining Applesoft - Random number generators "Michael J. Mahon" <mjmahon@aol.com> - 2016-03-02 20:49 -0800
                      Re: Streamlining Applesoft - Random number generators "Michael J. Mahon" <mjmahon@aol.com> - 2016-03-03 14:48 -0800
                Re: Streamlining Applesoft - Random number generators "Michael J. Mahon" <mjmahon@aol.com> - 2016-03-01 20:02 -0800
                  Re: Streamlining Applesoft - Random number generators Michael Pohoreski <michael.pohoreski@gmail.com> - 2016-03-03 07:48 -0800
                    Re: Streamlining Applesoft - Random number generators gids.rs@sasktel.net - 2016-03-03 08:05 -0800
                      Re: Streamlining Applesoft - Random number generators Michael Pohoreski <michael.pohoreski@gmail.com> - 2016-03-03 09:24 -0800
                    Re: Streamlining Applesoft - Random number generators Michael J. Mahon <mjmahon@aol.com> - 2016-03-03 22:51 -0600
                      Re: Streamlining Applesoft - Random number generators gids.rs@sasktel.net - 2016-03-03 21:34 -0800
                        Re: Streamlining Applesoft - Random number generators Michael J. Mahon <mjmahon@aol.com> - 2016-03-04 00:50 -0600
                          Re: Streamlining Applesoft - Random number generators Scott Hemphill <hemphill@hemphills.net> - 2016-03-04 10:47 -0500
                            Re: Streamlining Applesoft - Random number generators qkumba <peter.ferrie@gmail.com> - 2018-09-05 20:41 -0700
                              Re: Streamlining Applesoft - Random number generators Antoine Vignau <antoine.vignau@laposte.net> - 2018-09-06 09:13 -0700
                                Re: Streamlining Applesoft - Random number generators qkumba <peter.ferrie@gmail.com> - 2018-09-06 10:33 -0700
                              Re: Streamlining Applesoft - Random number generators Michael J. Mahon <mjmahon@aol.com> - 2018-09-06 17:58 -0500
    Re: Streamlining Applesoft - Random number generators John Brooks <jbrooks@blueshiftinc.com> - 2018-09-06 22:26 -0700
      Re: Streamlining Applesoft - Random number generators John Brooks <jbrooks@blueshiftinc.com> - 2018-09-07 18:08 -0700
      Re: Streamlining Applesoft - Random number generators John Brooks <jbrooks@blueshiftinc.com> - 2018-09-07 18:11 -0700
    Re: Streamlining Applesoft - Random number generators the.ertceps@gmail.com - 2018-09-29 05:03 -0700
      Re: Streamlining Applesoft - Random number generators James Davis <JPD.Enterprises@outlook.com> - 2018-09-29 10:24 -0700
        Re: Streamlining Applesoft - Random number generators Marco Verpelli <mverpelli@libero.it> - 2018-09-29 10:30 -0700
        Re: Streamlining Applesoft - Random number generators Brian Patrie <bpatrie@bellsouth.spamisicky.net> - 2018-09-29 12:36 -0500
          Re: Streamlining Applesoft - Random number generators Michael J. Mahon <mjmahon@aol.com> - 2018-09-29 12:41 -0500
            Re: Streamlining Applesoft - Random number generators Andy McFadden <thefadden@gmail.com> - 2018-09-29 21:06 -0700
            Re: Streamlining Applesoft - Random number generators James Davis <JPD.Enterprises@outlook.com> - 2018-09-30 19:28 -0700
              Re: Streamlining Applesoft - Random number generators "Frank M." <frank_o_rama@hotmail.com> - 2018-10-01 07:27 -0700

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#2420

From"Michael J. Mahon" <mjmahon@aol.com>
Date2016-03-02 20:49 -0800
Message-ID<w6WdnZOov-7eX0rLnZ2dnUU7-XXNnZ2d@giganews.com>
In reply to#2417
On 3/1/2016 10:03 PM, gids.rs@sasktel.net wrote:
> On Tuesday, March 1, 2016 at 9:24:53 PM UTC-6, mjm...@aol.com wrote:
>> On 3/1/2016 6:50 PM, Michael Pohoreski wrote:
>>> On Tuesday, March 1, 2016 at 3:28:19 PM UTC-8, mjm...@aol.com wrote:
>>>> I couldn't help it--I just had to determine the period of Applesoft's RND
>>>> function...  ;-)
>>>
>>> That's OK, you're in good company -- obsessed ^H^H^H inquiring minds want to know. :-)
>>>
>>>>   From a cold start without seeding, it cycles after 37758 calls. (Since
>>>> Applesoft doesn't fully initialize the seed,
>>>
>>> You wouldn't happen to remember where Applesoft inits RNDSEED ?
>>> I had found it and lost it again. :-/
>>>
>>>> this may vary depending on the
>>>> prior content of page zero.)
>>>
>>> Is 37758 the max period ?
>>>
>>> Hmm, I guess the F800 ROM random bytes (RNDL = $4E, RNDH = $4F) are never used.
>>>
>>> Hmm, looking over the disassembly I see RNDSEED is a 5 byte floating-point, using a simple linear congruential generator:
>>>
>>> C9-             RNDSEED        .EQ $C9 - CD
>>>
>>> EFA6- 98 35 44
>>> EFA9- 7A        CON.RND.1 .HS 9835447A  <<< THESE ARE MISSING ONE BYTE >>>
>>> EFAA- 68 28 B1
>>> EFAD- 46        CON.RND.2 .HS 6828B146  <<< FOR FP VALUES              >>>
>>>                   *--------------------------------
>>>                   *      "RND" FUNCTION
>>>                   *--------------------------------
>>> EFAE- 20 82 EB  RND    JSR SIGN     REDUCE ARGUMENT TO -1, 0, OR +1
>>> EFB1- AA               TAX          SAVE ARGUMENT
>>> EFB2- 30 18            BMI .1       = -1, USE CURRENT ARGUMENT FOR SEED
>>> EFB4- A9 C9            LDA #RNDSEED USE CURRENT SEED
>>> EFB6- A0 00            LDY /RNDSEED
>>> EFB8- 20 F9 EA         JSR LOAD.FAC.FROM.YA
>>> EFBB- 8A               TXA          RECALL SIGN OF ARGUMENT
>>> EFBC- F0 E7            BEQ RTS.19   =0, RETURN SEED UNCHANGED
>>> EFBE- A9 A6            LDA #CON.RND.1  VERY POOR RND ALGORITHM
>>> EFC0- A0 EF            LDY /CON.RND.1
>>> EFC2- 20 7F E9         JSR FMULT
>>> EFC5- A9 AA            LDA #CON.RND.2  ALSO, CONSTANTS ARE TRUNCATED
>>> EFC7- A0 EF            LDY /CON.RND.2  <<<THIS DOES NOTHING, DUE TO >>>
>>>                   *                      <<<SMALL EXPONENT            >>>
>>> EFC9- 20 BE E7         JSR FADD
>>> EFCC- A6 A1     .1     LDX FAC+4    SHUFFLE HI AND LO BYTES
>>> EFCE- A5 9E            LDA FAC+1    TO SUPPOSEDLY MAKE IT MORE RANDOM
>>> EFD0- 85 A1            STA FAC+4
>>> EFD2- 86 9E            STX FAC+1
>>> EFD4- A9 00            LDA #0       MAKE IT POSITIVE
>>> EFD6- 85 A2            STA FAC.SIGN
>>> EFD8- A5 9D            LDA FAC      A SOMEWHAT RANDOM EXTENSION
>>> EFDA- 85 AC            STA FAC.EXTENSION
>>> EFDC- A9 80            LDA #$80     EXPONENT TO MAKE VALUE < 1.0
>>> EFDE- 85 9D            STA FAC
>>> EFE0- 20 2E E8         JSR NORMALIZE.FAC.2
>>> EFE3- A2 C9            LDX #RNDSEED  MOVE FAC TO RND SEED
>>> EFE5- A0 00            LDY /RNDSEED
>>> EFE7- 4C 2B EB  GO.MOVMF JMP STORE.FAC.AT.YX.ROUNDED
>>>
>>> Did I get CON.RND.1 and CON.RND.2 right?
>>>
>>> ; CON.RND.1 EQU $EFA6; 11879546.4
>>> ; CON.RND.2 EQU $EFAA; 3.92767778E-08
>>>
>>> 300: LDA #$A6
>>>     LDY #$EF
>>>     JSR $EAF9 ; LOAD.FAC.YA
>>>     JSR $ED34 ; FOUT
>>>     JSR $E3E7 ; STRLIT
>>>     JMP $DACD ; STRPRT
>>>     LDA #AA
>>>     BNE $302
>>>
>>>
>>>> Seeded with RND(-2.71828), it cycles after 37758 calls (same cycle).
>>>
>>> I guess with a period of ~32K for an 8-bit CPU it isn't going to win any "good" distributions anytime soon. :-/
>>>
>>>> Seeded with RND(-3.14159), it cycles after only 202 calls!
>>>> This is a seriously broken PRNG!
>>>
>>> WOW -- that is horrible!!  Especially for a 5 byte seed!
>>>
>>> So this is a legitimate case of where we can blame Bill Gates? :-)
>>>
>>>> If we take 37758 as the typical cycle, and we take two RNDs per attempted
>>>> pixel set, there will be only 18879 different pairs of coordinates, so the
>>>> 53760 pixel HGR screen will stay mostly black.
>>>> If the cycle were an odd length, then as many as 37758 pixels might be set.
>>>
>>> Mind posting your test program per chance please? :-)
>>>
>>>
>>> Great investigation BTW !
>>
>> Thanks, but it's pretty trivial--it's fun to answer a question in a few
>> minutes at the keyboard.  ;-)
>>
>> Here's the program:
>>
>>    100  REM  RND Cycle Length Test
>>    110  REM     MJM - 03/01/16
>>    120 :
>>    130  REM  Empirical RND cycle is 37758 from cold start.
>>    140  REM                         37758 from seed with -2.71828
>>    150  REM                           202 from seed with -3.14159
>>    190  REM  200 not needed; RND cycles from the start.
>>    200  REM  FOR I = 1 TO 37758:X = RND (1): NEXT : REM Get into cycle
>>    205 X =  RND (1)
>>    210 :
>>    220  FOR I = 1 TO 100000:Y =  RND (1): IF X = Y GOTO 300
>>    230  NEXT
>>    290 :
>>    300  PRINT "RND cycle is "I" long."
>>
>> Note that since RND has only it's seed/previous result for state, once
>> it is seeded you are already in whatever cycle there will be, so no
>> initial cycling is needed (which is why line 200 is commented out).
>>
>> Contrast this with the shift register PRNG I posted earlier in this
>> thread, which has 32 bytes of internal state, holding eight parallel
>> 32-bit shift registers with a period of 2^32-1.
>> --
>>
>> -michael
>>
>
>
> Uhm!  Your test seems to fail, Michael.  If you poked the last byte into the seed from the prompt, it seems to run forever, but then try the test plot program.  The plotting still stops about the same time without the full 5 byte seedrun.
>
>
> 10 POKE 205,88:X=RND(1)
> 20 FOR I=1 TO 10000000:Y=RND(1):ONX=YGOTO100
> 30 NEXT
> 100 ? I" random numbers"
>
>
>    5 KB=49152: POKE 205,88
>   10  HGR : HCOLOR= 3: POKE 49234,0
>   20 X =  RND (1) * 280:Y =  RND (1) * 192:I=I+2
>   30  HPLOT X,Y: ON  PEEK (KB) < 128 GOTO 20
>
>
> After a few tests, I came to the determination that the applesoft code is not so much at fault as it is just a bad seed.  Even with the 5th byte.
>
> Try this seed that I came up with and try applesoft again.  Also instead of rebooting your computer each time, you can just poke in the original seed to get the same result.
>
> Here is a new test.
> Type HGR:RUN the first time, then RUN5  the second time.  Notice that line #30 never takes.  How full is the hi-res screen now?  Also line #50 can be used to keep track of a good seed that can be either saved to disk and re-entered later.
>
>
>   2 POKE 201,128: POKE 202,79: POKE 203,199: POKE 204,82: POKE 205,88
>   3 GOTO 10
>   5 POKE 205,88: J=1 :Z1 = RND(1):Z2=RND(2)
> 10 KB=49152: POKE 49232,0: HCOLOR=3: POKE 49234,0
> 20 X=RND(1)*280: Y=RND(1)*192
> 25 I=I+2:IF J=0 THEN IF I>57232 THEN ?CHR$(7):GOTO 50
> 30 IF X=Z1 OR X=Z2 THEN 50
> 35 IF J=1 THEN IF I>100000 THEN ?CHR$(7):GOTO 50
> 40 HPLOT X,Y: ON PEEK(KB)<128 GOTO 20
> 50 TEXT:?I: FOR J=0 TO 4:? PEEK(201+J),:NEXT

The reason that the test seemed to fail is that the RND generator was 
not yet in a cycle when the test started, so the initial random number 
never recurred within the cycle.  The remark in line 190 of my program 
is incorrect--a "run-in" is needed to get into the cycle before 
attempting to measure its length.

Here's a newer, more useful version of my program:

  100  REM  RND Cycle Length Test
  110  REM     MJM - 03/01/16
  115  REM  03/03/16 - Added seed POKEs and initial "run-in" to cycle
  120 :
  130  REM  RND cycle is 37758 (cold start after 6817 run-in)
  140  REM               37758 (seed with -2.71828 after 13218 run-in)
  150  REM (see note!) ==> 202 (seed with -3.14159 after 30771 run-in)
  160  REM                 202 (intended cold start after 15381 run-in)
  170  REM                 202 (seed with -4 or -5)
  180  REM               32366 (seed with -2, -3, or -6)
  190 :
  200  INPUT "Seed? (0=default, >0=intended, <0=seed): ";S
  210  POKE 201,128: POKE 202,79: POKE 203,199: POKE 204,82: POKE 205,255
  220  IF S = 0 GOTO 310: REM  Use default seed (with init bug)
  230  IF S > 0 THEN  POKE 205,88: GOTO 310: REM  Use intended seed
  240  REM  Else use supplied seed
  250 :
  300 X =  RND (S): REM  Optional seed
  310  FOR I = 1 TO 50000:X =  RND (1): NEXT : REM  Run-in to cycle
  320 :
  330 X =  RND (1): REM  Sample cycle for comparison
  340  GOSUB 430: REM  Print seed
  350 :
  360  FOR I = 1 TO 100000:Y =  RND (1): IF X = Y GOTO 390
  370  NEXT
  380 :
  390  PRINT "RND cycle is "I" long."
  400  GOSUB 430: REM  Print seed
  410  END
  420 :
  430  REM  Print the seed
  440 SEED = 201
  450  FOR J = 0 TO 4: PRINT  PEEK (SEED + J)" ";: NEXT : PRINT
  460  RETURN

First, the "note" referred to in line 150 is that I found a peculiarity 
in Applesoft:  if you INPUT -3.14159 into a variable and then call RND 
with that variable as an argument, the result is subtly different (low 
byte(s)?) from calling RND with the literal, e.g. RND(3.14159).

This was mildly surprising, but I left the result for the literal call 
in line 150 since I had taken the trouble to determine the required 
run-in using binary search.  ;-)

Now for the general comments...

Different seeds result in differing numbers of RND results which are 
*outside* the eventual cycle.  After this "run-in", you are in the cycle 
and it can be measured.  Since a cycle is a cycle, it doesn't matter if 
the run-in is longer than necessary (except for time), since once you're 
in the cycle, you stay there (until re-seeding).

As I mentioned, I determined a few actual run-in values by varying the 
run-in (using binary search) until I just entered the cycle.  Note that 
the longest run-in I found was just over 30,000 calls in, at which point 
RND entered a length 202 cycle.  So I took a stab at "enough" of a 
run-in at 50,000 calls.  This may not be large enough for some seeds,
but I'm guessing that it's plenty for such a rasty generator.

Trust me, the RND code is a disaster--it's not just the seed value!

Of course, it's OK for shuffling cards or rolling dice, but don't ever 
use it when you really need a lot of pseudorandom numbers.
-- 

-michael

NadaNet 3.1 for Apple II parallel computing!
Home page:  http://michaeljmahon.com

"The wastebasket is our most important design
tool--and it's seriously underused."

[toc] | [prev] | [next] | [standalone]


#2424

From"Michael J. Mahon" <mjmahon@aol.com>
Date2016-03-03 14:48 -0800
Message-ID<JsmdndHmlLu1IkXLnZ2dnUU7-fXNnZ2d@giganews.com>
In reply to#2420
On 3/2/2016 8:49 PM, Michael J. Mahon wrote:
> On 3/1/2016 10:03 PM, gids.rs@sasktel.net wrote:
>> On Tuesday, March 1, 2016 at 9:24:53 PM UTC-6, mjm...@aol.com wrote:
>>> On 3/1/2016 6:50 PM, Michael Pohoreski wrote:
>>>> On Tuesday, March 1, 2016 at 3:28:19 PM UTC-8, mjm...@aol.com wrote:
>>>>> I couldn't help it--I just had to determine the period of
>>>>> Applesoft's RND
>>>>> function...  ;-)
>>>>
>>>> That's OK, you're in good company -- obsessed ^H^H^H inquiring minds
>>>> want to know. :-)
>>>>
>>>>>   From a cold start without seeding, it cycles after 37758 calls.
>>>>> (Since
>>>>> Applesoft doesn't fully initialize the seed,
>>>>
>>>> You wouldn't happen to remember where Applesoft inits RNDSEED ?
>>>> I had found it and lost it again. :-/
>>>>
>>>>> this may vary depending on the
>>>>> prior content of page zero.)
>>>>
>>>> Is 37758 the max period ?
>>>>
>>>> Hmm, I guess the F800 ROM random bytes (RNDL = $4E, RNDH = $4F) are
>>>> never used.
>>>>
>>>> Hmm, looking over the disassembly I see RNDSEED is a 5 byte
>>>> floating-point, using a simple linear congruential generator:
>>>>
>>>> C9-             RNDSEED        .EQ $C9 - CD
>>>>
>>>> EFA6- 98 35 44
>>>> EFA9- 7A        CON.RND.1 .HS 9835447A  <<< THESE ARE MISSING ONE
>>>> BYTE >>>
>>>> EFAA- 68 28 B1
>>>> EFAD- 46        CON.RND.2 .HS 6828B146  <<< FOR FP
>>>> VALUES              >>>
>>>>                   *--------------------------------
>>>>                   *      "RND" FUNCTION
>>>>                   *--------------------------------
>>>> EFAE- 20 82 EB  RND    JSR SIGN     REDUCE ARGUMENT TO -1, 0, OR +1
>>>> EFB1- AA               TAX          SAVE ARGUMENT
>>>> EFB2- 30 18            BMI .1       = -1, USE CURRENT ARGUMENT FOR SEED
>>>> EFB4- A9 C9            LDA #RNDSEED USE CURRENT SEED
>>>> EFB6- A0 00            LDY /RNDSEED
>>>> EFB8- 20 F9 EA         JSR LOAD.FAC.FROM.YA
>>>> EFBB- 8A               TXA          RECALL SIGN OF ARGUMENT
>>>> EFBC- F0 E7            BEQ RTS.19   =0, RETURN SEED UNCHANGED
>>>> EFBE- A9 A6            LDA #CON.RND.1  VERY POOR RND ALGORITHM
>>>> EFC0- A0 EF            LDY /CON.RND.1
>>>> EFC2- 20 7F E9         JSR FMULT
>>>> EFC5- A9 AA            LDA #CON.RND.2  ALSO, CONSTANTS ARE TRUNCATED
>>>> EFC7- A0 EF            LDY /CON.RND.2  <<<THIS DOES NOTHING, DUE TO >>>
>>>>                   *                      <<<SMALL
>>>> EXPONENT            >>>
>>>> EFC9- 20 BE E7         JSR FADD
>>>> EFCC- A6 A1     .1     LDX FAC+4    SHUFFLE HI AND LO BYTES
>>>> EFCE- A5 9E            LDA FAC+1    TO SUPPOSEDLY MAKE IT MORE RANDOM
>>>> EFD0- 85 A1            STA FAC+4
>>>> EFD2- 86 9E            STX FAC+1
>>>> EFD4- A9 00            LDA #0       MAKE IT POSITIVE
>>>> EFD6- 85 A2            STA FAC.SIGN
>>>> EFD8- A5 9D            LDA FAC      A SOMEWHAT RANDOM EXTENSION
>>>> EFDA- 85 AC            STA FAC.EXTENSION
>>>> EFDC- A9 80            LDA #$80     EXPONENT TO MAKE VALUE < 1.0
>>>> EFDE- 85 9D            STA FAC
>>>> EFE0- 20 2E E8         JSR NORMALIZE.FAC.2
>>>> EFE3- A2 C9            LDX #RNDSEED  MOVE FAC TO RND SEED
>>>> EFE5- A0 00            LDY /RNDSEED
>>>> EFE7- 4C 2B EB  GO.MOVMF JMP STORE.FAC.AT.YX.ROUNDED
>>>>
>>>> Did I get CON.RND.1 and CON.RND.2 right?
>>>>
>>>> ; CON.RND.1 EQU $EFA6; 11879546.4
>>>> ; CON.RND.2 EQU $EFAA; 3.92767778E-08
>>>>
>>>> 300: LDA #$A6
>>>>     LDY #$EF
>>>>     JSR $EAF9 ; LOAD.FAC.YA
>>>>     JSR $ED34 ; FOUT
>>>>     JSR $E3E7 ; STRLIT
>>>>     JMP $DACD ; STRPRT
>>>>     LDA #AA
>>>>     BNE $302
>>>>
>>>>
>>>>> Seeded with RND(-2.71828), it cycles after 37758 calls (same cycle).
>>>>
>>>> I guess with a period of ~32K for an 8-bit CPU it isn't going to win
>>>> any "good" distributions anytime soon. :-/
>>>>
>>>>> Seeded with RND(-3.14159), it cycles after only 202 calls!
>>>>> This is a seriously broken PRNG!
>>>>
>>>> WOW -- that is horrible!!  Especially for a 5 byte seed!
>>>>
>>>> So this is a legitimate case of where we can blame Bill Gates? :-)
>>>>
>>>>> If we take 37758 as the typical cycle, and we take two RNDs per
>>>>> attempted
>>>>> pixel set, there will be only 18879 different pairs of coordinates,
>>>>> so the
>>>>> 53760 pixel HGR screen will stay mostly black.
>>>>> If the cycle were an odd length, then as many as 37758 pixels might
>>>>> be set.
>>>>
>>>> Mind posting your test program per chance please? :-)
>>>>
>>>>
>>>> Great investigation BTW !
>>>
>>> Thanks, but it's pretty trivial--it's fun to answer a question in a few
>>> minutes at the keyboard.  ;-)
>>>
>>> Here's the program:
>>>
>>>    100  REM  RND Cycle Length Test
>>>    110  REM     MJM - 03/01/16
>>>    120 :
>>>    130  REM  Empirical RND cycle is 37758 from cold start.
>>>    140  REM                         37758 from seed with -2.71828
>>>    150  REM                           202 from seed with -3.14159
>>>    190  REM  200 not needed; RND cycles from the start.
>>>    200  REM  FOR I = 1 TO 37758:X = RND (1): NEXT : REM Get into cycle
>>>    205 X =  RND (1)
>>>    210 :
>>>    220  FOR I = 1 TO 100000:Y =  RND (1): IF X = Y GOTO 300
>>>    230  NEXT
>>>    290 :
>>>    300  PRINT "RND cycle is "I" long."
>>>
>>> Note that since RND has only it's seed/previous result for state, once
>>> it is seeded you are already in whatever cycle there will be, so no
>>> initial cycling is needed (which is why line 200 is commented out).
>>>
>>> Contrast this with the shift register PRNG I posted earlier in this
>>> thread, which has 32 bytes of internal state, holding eight parallel
>>> 32-bit shift registers with a period of 2^32-1.
>>> --
>>>
>>> -michael
>>>
>>
>>
>> Uhm!  Your test seems to fail, Michael.  If you poked the last byte
>> into the seed from the prompt, it seems to run forever, but then try
>> the test plot program.  The plotting still stops about the same time
>> without the full 5 byte seedrun.
>>
>>
>> 10 POKE 205,88:X=RND(1)
>> 20 FOR I=1 TO 10000000:Y=RND(1):ONX=YGOTO100
>> 30 NEXT
>> 100 ? I" random numbers"
>>
>>
>>    5 KB=49152: POKE 205,88
>>   10  HGR : HCOLOR= 3: POKE 49234,0
>>   20 X =  RND (1) * 280:Y =  RND (1) * 192:I=I+2
>>   30  HPLOT X,Y: ON  PEEK (KB) < 128 GOTO 20
>>
>>
>> After a few tests, I came to the determination that the applesoft code
>> is not so much at fault as it is just a bad seed.  Even with the 5th
>> byte.
>>
>> Try this seed that I came up with and try applesoft again.  Also
>> instead of rebooting your computer each time, you can just poke in the
>> original seed to get the same result.
>>
>> Here is a new test.
>> Type HGR:RUN the first time, then RUN5  the second time.  Notice that
>> line #30 never takes.  How full is the hi-res screen now?  Also line
>> #50 can be used to keep track of a good seed that can be either saved
>> to disk and re-entered later.
>>
>>
>>   2 POKE 201,128: POKE 202,79: POKE 203,199: POKE 204,82: POKE 205,88
>>   3 GOTO 10
>>   5 POKE 205,88: J=1 :Z1 = RND(1):Z2=RND(2)
>> 10 KB=49152: POKE 49232,0: HCOLOR=3: POKE 49234,0
>> 20 X=RND(1)*280: Y=RND(1)*192
>> 25 I=I+2:IF J=0 THEN IF I>57232 THEN ?CHR$(7):GOTO 50
>> 30 IF X=Z1 OR X=Z2 THEN 50
>> 35 IF J=1 THEN IF I>100000 THEN ?CHR$(7):GOTO 50
>> 40 HPLOT X,Y: ON PEEK(KB)<128 GOTO 20
>> 50 TEXT:?I: FOR J=0 TO 4:? PEEK(201+J),:NEXT
>
> The reason that the test seemed to fail is that the RND generator was
> not yet in a cycle when the test started, so the initial random number
> never recurred within the cycle.  The remark in line 190 of my program
> is incorrect--a "run-in" is needed to get into the cycle before
> attempting to measure its length.
>
> Here's a newer, more useful version of my program:
>
>   100  REM  RND Cycle Length Test
>   110  REM     MJM - 03/01/16
>   115  REM  03/03/16 - Added seed POKEs and initial "run-in" to cycle
>   120 :
>   130  REM  RND cycle is 37758 (cold start after 6817 run-in)
>   140  REM               37758 (seed with -2.71828 after 13218 run-in)
>   150  REM (see note!) ==> 202 (seed with -3.14159 after 30771 run-in)
>   160  REM                 202 (intended cold start after 15381 run-in)
>   170  REM                 202 (seed with -4 or -5)
>   180  REM               32366 (seed with -2, -3, or -6)
>   190 :
>   200  INPUT "Seed? (0=default, >0=intended, <0=seed): ";S
>   210  POKE 201,128: POKE 202,79: POKE 203,199: POKE 204,82: POKE 205,255
>   220  IF S = 0 GOTO 310: REM  Use default seed (with init bug)
>   230  IF S > 0 THEN  POKE 205,88: GOTO 310: REM  Use intended seed
>   240  REM  Else use supplied seed
>   250 :
>   300 X =  RND (S): REM  Optional seed
>   310  FOR I = 1 TO 50000:X =  RND (1): NEXT : REM  Run-in to cycle
>   320 :
>   330 X =  RND (1): REM  Sample cycle for comparison
>   340  GOSUB 430: REM  Print seed
>   350 :
>   360  FOR I = 1 TO 100000:Y =  RND (1): IF X = Y GOTO 390
>   370  NEXT
>   380 :
>   390  PRINT "RND cycle is "I" long."
>   400  GOSUB 430: REM  Print seed
>   410  END
>   420 :
>   430  REM  Print the seed
>   440 SEED = 201
>   450  FOR J = 0 TO 4: PRINT  PEEK (SEED + J)" ";: NEXT : PRINT
>   460  RETURN
>
> First, the "note" referred to in line 150 is that I found a peculiarity
> in Applesoft:  if you INPUT -3.14159 into a variable and then call RND
> with that variable as an argument, the result is subtly different (low
> byte(s)?) from calling RND with the literal, e.g. RND(3.14159).
>
> This was mildly surprising, but I left the result for the literal call
> in line 150 since I had taken the trouble to determine the required
> run-in using binary search.  ;-)
>
> Now for the general comments...
>
> Different seeds result in differing numbers of RND results which are
> *outside* the eventual cycle.  After this "run-in", you are in the cycle
> and it can be measured.  Since a cycle is a cycle, it doesn't matter if
> the run-in is longer than necessary (except for time), since once you're
> in the cycle, you stay there (until re-seeding).
>
> As I mentioned, I determined a few actual run-in values by varying the
> run-in (using binary search) until I just entered the cycle.  Note that
> the longest run-in I found was just over 30,000 calls in, at which point
> RND entered a length 202 cycle.  So I took a stab at "enough" of a
> run-in at 50,000 calls.  This may not be large enough for some seeds,
> but I'm guessing that it's plenty for such a rasty generator.
>
> Trust me, the RND code is a disaster--it's not just the seed value!
>
> Of course, it's OK for shuffling cards or rolling dice, but don't ever
> use it when you really need a lot of pseudorandom numbers.

I got tired of doing the binary search for entry to the cycle by hand, 
so here's a new version of the RND.CYCLE program that accepts any key 
and determines the length of the eventual cycle and the length of the 
run-in to the cycle.

  100  REM  RND Cycle Length Test
  110  REM     MJM - 03/01/16
  120  REM  03/02/16 - Added seed POKEs and initial "run-in" to cycle
  130  REM  03/03/16 - Added binary search for "run-in" to cycle
  140 :
  150  REM  RND cycle is 37758 (cold start after 6817 run-in)
  160  REM                 202 (intended cold start after 15381 run-in)
  170  REM               37758 (seed with -2.71828 after 13218 run-in)
  180  REM               37758 (seed with -3.14159 after 9256 run-in)
  190  REM  (note!) ==>  37758 (seed with -3.14159 after 6817 run-in)
  200  REM               32366 (seed with -2 after 3887 run-in)
  210  REM               32366 (seed with -3 after 22481 run-in)
  220  REM                 202 (seed with -4 after 22731 run-in)
  230  REM                 202 (seed with -5 after 36775 run-in)
  240  REM               32366 (seed with -6 after 7912 run-in)
  250 :
  300 RI = 50000:ST =  INT (RI + .7) / 2:CY = 100000
  310  INPUT "Seed? (0=default, >0=intended, <0=seed): ";S
  320  POKE 201,128: POKE 202,79: POKE 203,199: POKE 204,82: POKE 205,255
  330  IF S = 0 GOTO 420: REM  Use default seed (with init bug)
  340  IF S > 0 THEN  POKE 205,88: GOTO 420: REM  Use intended seed
  350  REM  Else use supplied seed
  360 :
  400 X =  RND (S): REM  Optional seed
  420  PRINT "Run-in = "RI", step = "ST", cycle = "CY - 5
  430  FOR I = 1 TO RI:X =  RND (1): NEXT : REM  Run-in to cycle
  440 :
  450 X =  RND (1): REM  Sample cycle for comparison
  460 :
  470  FOR I = 1 TO CY:Y =  RND (1): IF X = Y GOTO 540
  480  NEXT
  490 :
  500  REM  Not in cycle, increase run-in by step and try again
  510 RI = RI + ST:ST =  INT (ST / 2 + .7)
  520  GOTO 320
  530 :
  540  IF ST = 1 GOTO 600
  550  REM  In cycle. Decrease RI and CY and try again
  560 RI = RI - ST:CY = I + 5
  570 ST =  INT (ST / 2 + .7)
  580  GOTO 320
  590 :
  600  PRINT "RND run-in is "RI
  610  PRINT "RND cycle is "I" long."
  620  END

It seems that any seed will, pretty quickly, enter a cycle.  There are 
apparently several cycles of various lengths, including one just 202 
numbers long!

-michael

NadaNet 3.1 for Apple II parallel computing!
Home page:  http://michaeljmahon.com

"The wastebasket is our most important design
tool--and it's seriously underused."

[toc] | [prev] | [next] | [standalone]


#2416

From"Michael J. Mahon" <mjmahon@aol.com>
Date2016-03-01 20:02 -0800
Message-ID<xaudncrlbLxK-EvLnZ2dnUU7-LfNnZ2d@giganews.com>
In reply to#2414
On 3/1/2016 6:50 PM, Michael Pohoreski wrote:
> On Tuesday, March 1, 2016 at 3:28:19 PM UTC-8, mjm...@aol.com wrote:
>> I couldn't help it--I just had to determine the period of Applesoft's RND
>> function...  ;-)
>
> That's OK, you're in good company -- obsessed ^H^H^H inquiring minds want to know. :-)
>
>>  From a cold start without seeding, it cycles after 37758 calls. (Since
>> Applesoft doesn't fully initialize the seed,
>
> You wouldn't happen to remember where Applesoft inits RNDSEED ?
> I had found it and lost it again. :-/
>
>> this may vary depending on the
>> prior content of page zero.)
>
> Is 37758 the max period ?
>
> Hmm, I guess the F800 ROM random bytes (RNDL = $4E, RNDH = $4F) are never used.
>
> Hmm, looking over the disassembly I see RNDSEED is a 5 byte floating-point, using a simple linear congruential generator:
>
> C9-             RNDSEED        .EQ $C9 - CD
>
> EFA6- 98 35 44
> EFA9- 7A        CON.RND.1 .HS 9835447A  <<< THESE ARE MISSING ONE BYTE >>>
> EFAA- 68 28 B1
> EFAD- 46        CON.RND.2 .HS 6828B146  <<< FOR FP VALUES              >>>
>                  *--------------------------------
>                  *      "RND" FUNCTION
>                  *--------------------------------
> EFAE- 20 82 EB  RND    JSR SIGN     REDUCE ARGUMENT TO -1, 0, OR +1
> EFB1- AA               TAX          SAVE ARGUMENT
> EFB2- 30 18            BMI .1       = -1, USE CURRENT ARGUMENT FOR SEED
> EFB4- A9 C9            LDA #RNDSEED USE CURRENT SEED
> EFB6- A0 00            LDY /RNDSEED
> EFB8- 20 F9 EA         JSR LOAD.FAC.FROM.YA
> EFBB- 8A               TXA          RECALL SIGN OF ARGUMENT
> EFBC- F0 E7            BEQ RTS.19   =0, RETURN SEED UNCHANGED
> EFBE- A9 A6            LDA #CON.RND.1  VERY POOR RND ALGORITHM
> EFC0- A0 EF            LDY /CON.RND.1
> EFC2- 20 7F E9         JSR FMULT
> EFC5- A9 AA            LDA #CON.RND.2  ALSO, CONSTANTS ARE TRUNCATED
> EFC7- A0 EF            LDY /CON.RND.2  <<<THIS DOES NOTHING, DUE TO >>>
>                  *                      <<<SMALL EXPONENT            >>>
> EFC9- 20 BE E7         JSR FADD
> EFCC- A6 A1     .1     LDX FAC+4    SHUFFLE HI AND LO BYTES
> EFCE- A5 9E            LDA FAC+1    TO SUPPOSEDLY MAKE IT MORE RANDOM
> EFD0- 85 A1            STA FAC+4
> EFD2- 86 9E            STX FAC+1
> EFD4- A9 00            LDA #0       MAKE IT POSITIVE
> EFD6- 85 A2            STA FAC.SIGN
> EFD8- A5 9D            LDA FAC      A SOMEWHAT RANDOM EXTENSION
> EFDA- 85 AC            STA FAC.EXTENSION
> EFDC- A9 80            LDA #$80     EXPONENT TO MAKE VALUE < 1.0
> EFDE- 85 9D            STA FAC
> EFE0- 20 2E E8         JSR NORMALIZE.FAC.2
> EFE3- A2 C9            LDX #RNDSEED  MOVE FAC TO RND SEED
> EFE5- A0 00            LDY /RNDSEED
> EFE7- 4C 2B EB  GO.MOVMF JMP STORE.FAC.AT.YX.ROUNDED
>
> Did I get CON.RND.1 and CON.RND.2 right?
>
> ; CON.RND.1 EQU $EFA6; 11879546.4
> ; CON.RND.2 EQU $EFAA; 3.92767778E-08
>
> 300: LDA #$A6
>    LDY #$EF
>    JSR $EAF9 ; LOAD.FAC.YA
>    JSR $ED34 ; FOUT
>    JSR $E3E7 ; STRLIT
>    JMP $DACD ; STRPRT
>    LDA #AA
>    BNE $302
>
>
>> Seeded with RND(-2.71828), it cycles after 37758 calls (same cycle).
>
> I guess with a period of ~32K for an 8-bit CPU it isn't going to win any "good" distributions anytime soon. :-/
>
>> Seeded with RND(-3.14159), it cycles after only 202 calls!
>> This is a seriously broken PRNG!
>
> WOW -- that is horrible!!  Especially for a 5 byte seed!
>
> So this is a legitimate case of where we can blame Bill Gates? :-)
>
>> If we take 37758 as the typical cycle, and we take two RNDs per attempted
>> pixel set, there will be only 18879 different pairs of coordinates, so the
>> 53760 pixel HGR screen will stay mostly black.
>> If the cycle were an odd length, then as many as 37758 pixels might be set.
>
> Mind posting your test program per chance please? :-)
>
>
> Great investigation BTW !

Here, from Bob Sander-Cederlof's disassembly of Applesoft, is the 
COLD_START routine that incorrectly initializes the RND seed.  This code 
snippet starts at $F10B in the ROM.

Combined with the "mantissa-only" bug in the RND routine itself, this 
routine is a disaster.

One of the problems with a PRNG is that it's not as easy to test as a 
math function, like SIN or SQR, and clearly RND didn't get much testing!

;--------------------------------
;      GENERIC COPY OF CHRGET SUBROUTINE, WHICH
;      IS COPIED INTO $00B1...$00C8 DURING INITIALIZATION
;
;      CORNELIS BONGERS DESCRIBED SEVERAL IMPROVEMENTS
;      TO CHRGET IN MICRO MAGAZINE OR CALL A_P.P.L_E.
;      (I DON'T REMEMBER WHICH OR EXACTLY WHEN)
;--------------------------------
GENERIC_CHRGET:
        INC TXTPTR
        BNE @1
        INC TXTPTR+1
@1:    LDA $EA60    ;<<< ACTUAL ADDRESS FILLED IN LATER >>>
        CMP #':'     ;EOS, ALSO TOP OF NUMERIC RANGE
        BCS @2       ;NOT NUMBER, MIGHT BE EOS
        CMP #' '     ;IGNORE BLANKS
        BEQ GENERIC_CHRGET
        SEC          ;TEST FOR NUMERIC RANGE IN WAY THAT
        SBC #'0'     ;CLEARS CARRY IF CHAR IS DIGIT
        SEC          ;AND LEAVES CHAR IN A-REG
        SBC #-'0'
@2:    RTS
;--------------------------------
;      INITIAL VALUE FOR RANDOM NUMBER, ALSO COPIED
;      IN ALONG WITH CHRGET, BUT ERRONEOUSLY:
;  <<< THE LAST BYTE IS NOT COPIED >>>
;--------------------------------
;      .HS 804FC75258  APPROX. = .81163515
        .byte $80, $4F, $C7, $52, $58
GENERIC_END:
;--------------------------------
COLD_START:
        LDX #$FF     ;SET DIRECT MODE FLAG
        STX CURLIN+1
        LDX #$FB     ;SET STACK POINTER, LEAVING ROOM FOR
        TXS          ;LINE BUFFER DURING PARSING
        LDA #<COLD_START   ;SET RESTART TO COLD_START
        LDY #>COLD_START   ;UNTIL COLDSTART IS COMPLETED
        STA GOWARM+1
        STY GOWARM+2
        STA GOSTROUT+1    ;ALSO SECOND USER VECTOR_..
        STY GOSTROUT+2  ;..WE SIMPLY MUST FINISH COLD_START!
        JSR NORMAL        ;SET NORMAL DISPLAY MODE
        LDA #$4C          ;"JMP" OPCODE FOR 4 VECTORS
        STA GOWARM        ;WARM START
        STA GOSTROUT      ;ANYONE EVER USE THIS ONE?
        STA JMPADRS       ;USED BY FUNCTIONS (JSR JMPADRS)
        STA USR           ;"USR" FUNCTION VECTOR
        LDA #<IQERR        ;POINT "USR" TO ILLEGAL QUANTITY
        LDY #>IQERR        ;ERROR, UNTIL USER SETS IT UP
        STA USR+1
        STY USR+2
;--------------------------------
;      MOVE GENERIC CHRGET AND RANDOM SEED INTO PLACE
;
;  <<< NOTE THAT LOOP VALUE IS WRONG!          >>>
;  <<< THE LAST BYTE OF THE RANDOM SEED IS NOT >>>
;  <<< COPIED INTO PAGE ZERO!                  >>>
;--------------------------------
        LDX #GENERIC_END-GENERIC_CHRGET-1
@1:    LDA GENERIC_CHRGET-1,X
        STA CHRGET-1,X
        STX SPEEDZ        ;ON LAST PASS STORES $01)
        DEX
        BNE @1
;--------------------------------


-- 

-michael

NadaNet 3.1 for Apple II parallel computing!
Home page:  http://michaeljmahon.com

"The wastebasket is our most important design
tool--and it's seriously underused."

[toc] | [prev] | [next] | [standalone]


#2421

FromMichael Pohoreski <michael.pohoreski@gmail.com>
Date2016-03-03 07:48 -0800
Message-ID<6d52de94-fc33-423d-abdb-fad2ec5af67e@googlegroups.com>
In reply to#2416
On Tuesday, March 1, 2016 at 8:02:32 PM UTC-8, mjm...@aol.com wrote:
> Here, from Bob Sander-Cederlof's disassembly of Applesoft, is the 
> COLD_START routine that incorrectly initializes the RND seed.  This code 
> snippet starts at $F10B in the ROM.
> 
> Combined with the "mantissa-only" bug in the RND routine itself, this 
> routine is a disaster.

Thanks Michael! That's *exactly* the code I was thinking of -- just couldn't remember the name (or location).

Pity that AppleSoft doesn't use the 16-bit RNDL and RNDH as part of its seed. :-/

Off-topic: So it's Applesoft that copies code into the zero page -- **grr**.

[toc] | [prev] | [next] | [standalone]


#2422

Fromgids.rs@sasktel.net
Date2016-03-03 08:05 -0800
Message-ID<cbeb44d3-b7ef-486f-982f-dafebf271b97@googlegroups.com>
In reply to#2421
> Pity that AppleSoft doesn't use the 16-bit RNDL and RNDH as part of its seed. :-/
> 
> Off-topic: So it's Applesoft that copies code into the zero page -- **grr**.



That doesn't mean you can't copy over it once your program gets control. :)
Just reseed with your own seed.

[toc] | [prev] | [next] | [standalone]


#2423

FromMichael Pohoreski <michael.pohoreski@gmail.com>
Date2016-03-03 09:24 -0800
Message-ID<dc132c99-920e-4b8d-b9b9-ac3b04f1097b@googlegroups.com>
In reply to#2422
On Thursday, March 3, 2016 at 8:05:13 AM UTC-8, gid...@sasktel.net wrote:
> > Pity that AppleSoft doesn't use the 16-bit RNDL and RNDH as part of its seed. :-/
> That doesn't mean you can't copy over it once your program gets control. :)
> Just reseed with your own seed.

Touché. :-)

[toc] | [prev] | [next] | [standalone]


#2425

FromMichael J. Mahon <mjmahon@aol.com>
Date2016-03-03 22:51 -0600
Message-ID<ysydnSecMKD8iUTLnZ2dnUU7-LHNnZ2d@giganews.com>
In reply to#2421
Michael Pohoreski <michael.pohoreski@gmail.com> wrote:
> On Tuesday, March 1, 2016 at 8:02:32 PM UTC-8, mjm...@aol.com wrote:
>> Here, from Bob Sander-Cederlof's disassembly of Applesoft, is the 
>> COLD_START routine that incorrectly initializes the RND seed.  This code 
>> snippet starts at $F10B in the ROM.
>> 
>> Combined with the "mantissa-only" bug in the RND routine itself, this 
>> routine is a disaster.
> 
> Thanks Michael! That's *exactly* the code I was thinking of -- just
> couldn't remember the name (or location).
> 
> Pity that AppleSoft doesn't use the 16-bit RNDL and RNDH as part of its seed. :-/

When debugging, you want deterministic pseudorandom numbers.  You can
always PEEK the GETCHR counter and use it to seed RND if you want a
different set each time. 

By default, RND delivers the same sequence each time after a cold start
(assuming that the uninitialized low byte of the seed powers up in the same
state ;-).

If you really want to be sure the same sequence occurs on each run, you
should seed RND at the start of your program, though a good fraction of
seeds seem to deliver a modest pseudorandom sequence followed by a short
cycle...
-- 
-michael - NadaNet 3.1 and AppleCrate II:  http://michaeljmahon.com

[toc] | [prev] | [next] | [standalone]


#2426

Fromgids.rs@sasktel.net
Date2016-03-03 21:34 -0800
Message-ID<b798ece7-5b0d-44d6-ab1d-aee6dee0e8ab@googlegroups.com>
In reply to#2425
> > Thanks Michael! That's *exactly* the code I was thinking of -- just
> > couldn't remember the name (or location).
> > 
> > Pity that AppleSoft doesn't use the 16-bit RNDL and RNDH as part of its seed. :-/
> 
> When debugging, you want deterministic pseudorandom numbers.  You can
> always PEEK the GETCHR counter and use it to seed RND if you want a
> different set each time. 
> 
> By default, RND delivers the same sequence each time after a cold start
> (assuming that the uninitialized low byte of the seed powers up in the same
> state ;-).
> 
> If you really want to be sure the same sequence occurs on each run, you
> should seed RND at the start of your program, though a good fraction of
> seeds seem to deliver a modest pseudorandom sequence followed by a short
> cycle...


For the IIGS anyways, I think the VBL and HBL would be an excellent source for a seed on startup.  These values are always random and when used in conjunction with RNDL and RNDH can give a 4-byte random seed, and you can even give a random key press for a 5th byte, different every time on bootup.

I use this for a 5 byte random seed in Sweet 16 and GSPORT and real IIGS.
I believe this should work in a IIc as well but not II+ or IIe's standard or enhanced.

]LOOP INC $4E
 BNE NOTHI
 INC $4F
NOTHI BIT $C000
 BPL ]LOOP
 LDA $C010
 STA $C9
 LDX $C02E
 LDA $C02F
 STX $CD
 STA $CC
 LDA $4E
 LDX $4F
 STA $CB
 STX $C9
...


test to see if your computer's VBL or HBL gives values with this:

300: LDX $C02E
 LDA $C02F
 JSR $F941
 BIT $C000
 BPL $300
 BIT $C010
 RTS

[toc] | [prev] | [next] | [standalone]


#2427

FromMichael J. Mahon <mjmahon@aol.com>
Date2016-03-04 00:50 -0600
Message-ID<7NadnThcNNnNrUTLnZ2dnUU7-KfNnZ2d@giganews.com>
In reply to#2426
<gids.rs@sasktel.net> wrote:
>>> Thanks Michael! That's *exactly* the code I was thinking of -- just
>>> couldn't remember the name (or location).
>>> 
>>> Pity that AppleSoft doesn't use the 16-bit RNDL and RNDH as part of its seed. :-/
>> 
>> When debugging, you want deterministic pseudorandom numbers.  You can
>> always PEEK the GETCHR counter and use it to seed RND if you want a
>> different set each time. 
>> 
>> By default, RND delivers the same sequence each time after a cold start
>> (assuming that the uninitialized low byte of the seed powers up in the same
>> state ;-).
>> 
>> If you really want to be sure the same sequence occurs on each run, you
>> should seed RND at the start of your program, though a good fraction of
>> seeds seem to deliver a modest pseudorandom sequence followed by a short
>> cycle...
> 
> 
> For the IIGS anyways, I think the VBL and HBL would be an excellent
> source for a seed on startup.  These values are always random and when
> used in conjunction with RNDL and RNDH can give a 4-byte random seed, and
> you can even give a random key press for a 5th byte, different every time on bootup.
> 
> I use this for a 5 byte random seed in Sweet 16 and GSPORT and real IIGS.
> I believe this should work in a IIc as well but not II+ or IIe's standard or enhanced.
> 
> ]LOOP INC $4E
>  BNE NOTHI
>  INC $4F
> NOTHI BIT $C000
>  BPL ]LOOP
>  LDA $C010
>  STA $C9
>  LDX $C02E
>  LDA $C02F
>  STX $CD
>  STA $CC
>  LDA $4E
>  LDX $4F
>  STA $CB
>  STX $C9
> ...
> 
> 
> test to see if your computer's VBL or HBL gives values with this:
> 
> 300: LDX $C02E
>  LDA $C02F
>  JSR $F941
>  BIT $C000
>  BPL $300
>  BIT $C010
>  RTS
> 

When you seed a random number generator you are only selecting a point in
the generators cycle where you want to start. 

A good generator will have a very long cycle, but every generator has at
least one cycle, and a good generator has only one, maximal length cycle.  

So if you have a two-byte seed, you are randomly selecting one of 2^16
starting points in the cycle. A longer seed does not make the numbers more
random, it just selects from a larger number of starting points. The
quality of a PRNG is not determined by its seed, but only by its algorithm.


I'd guess that 2^16 different sequences of pseudorandom numbers is more
than enough for any application. 

In the case of Applesoft's RND generator, it is so riddled with short
cycles that seeding with a random (and therefore untested) seed has a high
probability of producing a short, degenerate sequence. Better to select
from a small set of seeds that have been verified to generate at least a
few thousand different numbers. 

Of course, it's actually best to avoid RND entirely for any serious work. 
-- 
-michael - NadaNet 3.1 and AppleCrate II:  http://michaeljmahon.com

[toc] | [prev] | [next] | [standalone]


#2429

FromScott Hemphill <hemphill@hemphills.net>
Date2016-03-04 10:47 -0500
Message-ID<87ziue2qke.fsf@hemphills.net>
In reply to#2427
Michael J. Mahon <mjmahon@aol.com> writes:

> <gids.rs@sasktel.net> wrote:
>>>> Thanks Michael! That's *exactly* the code I was thinking of -- just
>>>> couldn't remember the name (or location).
>>>> 
>>>> Pity that AppleSoft doesn't use the 16-bit RNDL and RNDH as part
>>>> of its seed. :-/
>>> 
>>> When debugging, you want deterministic pseudorandom numbers.  You can
>>> always PEEK the GETCHR counter and use it to seed RND if you want a
>>> different set each time. 
>>> 
>>> By default, RND delivers the same sequence each time after a cold start
>>> (assuming that the uninitialized low byte of the seed powers up in the same
>>> state ;-).
>>> 
>>> If you really want to be sure the same sequence occurs on each run, you
>>> should seed RND at the start of your program, though a good fraction of
>>> seeds seem to deliver a modest pseudorandom sequence followed by a short
>>> cycle...
>> 
>> 
>> For the IIGS anyways, I think the VBL and HBL would be an excellent
>> source for a seed on startup.  These values are always random and when
>> used in conjunction with RNDL and RNDH can give a 4-byte random seed, and
>> you can even give a random key press for a 5th byte, different every
>> time on bootup.
>> 
>> I use this for a 5 byte random seed in Sweet 16 and GSPORT and real IIGS.
>> I believe this should work in a IIc as well but not II+ or IIe's
>> standard or enhanced.
>> 
>> ]LOOP INC $4E
>>  BNE NOTHI
>>  INC $4F
>> NOTHI BIT $C000
>>  BPL ]LOOP
>>  LDA $C010
>>  STA $C9
>>  LDX $C02E
>>  LDA $C02F
>>  STX $CD
>>  STA $CC
>>  LDA $4E
>>  LDX $4F
>>  STA $CB
>>  STX $C9
>> ...
>> 
>> 
>> test to see if your computer's VBL or HBL gives values with this:
>> 
>> 300: LDX $C02E
>>  LDA $C02F
>>  JSR $F941
>>  BIT $C000
>>  BPL $300
>>  BIT $C010
>>  RTS
>> 
>
> When you seed a random number generator you are only selecting a point in
> the generators cycle where you want to start. 
>
> A good generator will have a very long cycle, but every generator has at
> least one cycle, and a good generator has only one, maximal length cycle.  
>
> So if you have a two-byte seed, you are randomly selecting one of 2^16
> starting points in the cycle. A longer seed does not make the numbers more
> random, it just selects from a larger number of starting points. The
> quality of a PRNG is not determined by its seed, but only by its algorithm.
>
>
> I'd guess that 2^16 different sequences of pseudorandom numbers is more
> than enough for any application. 
>
> In the case of Applesoft's RND generator, it is so riddled with short
> cycles that seeding with a random (and therefore untested) seed has a high
> probability of producing a short, degenerate sequence. Better to select
> from a small set of seeds that have been verified to generate at least a
> few thousand different numbers. 
>
> Of course, it's actually best to avoid RND entirely for any serious work. 

I used a high-quality linear congruential generator in my 3D tic-tac-toe
program.  I was just going to say something about it, and I found this
URL in my program comments:

http://www.6502.org/source/integers/random/random.html

Scott
-- 
Scott Hemphill	hemphill@alumni.caltech.edu
"This isn't flying.  This is falling, with style."  -- Buzz Lightyear

[toc] | [prev] | [next] | [standalone]


#4750

Fromqkumba <peter.ferrie@gmail.com>
Date2018-09-05 20:41 -0700
Message-ID<03b0c495-f0c0-404b-82ec-7694ed8f71f3@googlegroups.com>
In reply to#2429
Okay, finally I returned to the SQR code.
Here's the whole source with my changes.
It caches the temp1 in X instead of zpage, so it shaves 7(?) cycles per iteration.
To save two bytes, you could omit the "bne :start ; (always)" but it would cost 31 cycles.

**********************************************************
*                                                        *
*                SQR (X)  as  USR (X)                    *
*                                                        *
*                  Michael J. Mahon                      *
*                   April 03, 2009                       *
*                   Copyright 2009                       *
*                                                        *
*  Called by USR(X), computes square root of X using a   *
*  direct non-restoring algorithm requiring about 5.2    *
*  milliseconds on a 1MHz processor, or about nine times *
*  faster than the Applesoft SQR function.               *
*                                                        *
*  USR.SQR is location-independent, and so may be BRUN   *
*  at any location to install it as the USR function.    *
*                                                        *
**********************************************************

* Applesoft Page Zero Definitions

USR equ $0A ; JMP to USR function
FAC equ $9D ; Floating-Point Accumulator
FACSGN equ FAC+5 ; FAC unpacked sign
EXTRAFAC equ $AC ; FAC guard byte
TEMP1 equ $93 ; Temp FP storage
ARG equ $A5 ; Aux FAC

* Apple ROM routines

IQERR equ $E199 ; "Illegal Quantity Error"
MOVAF equ $EB63 ; Move rounded FAC to ARG
IORTS equ $FF58 ; Location of RTS

* Macro Definitions

rol32 mac  ; Rotate 32 bit int left
 rol ]1+3
 rol ]1+2
 rol ]1+1
 rol
 eom

asl32 mac  ; Shift 32 bit int left
 asl ]1+3
 rol ]1+2
 rol ]1+1
 rol ]1
 eom
 pag
 org $310

* Set up USR jump to go to sqr

entry jsr IORTS ; Get entry+2 on stack
 tsx
 clc
 ldaa $100-1,x ; Lo byte of entry+2
 adc #<]offset ; Lo byte of sqr
 sta USR+1
 ldaa $100,x ; Hi byte of entry+2
 adc #>]offset ; Hi byte of sqr
 sta USR+2
rts rts
 pag
* Square Root function

sqr lda FAC ; Is FAC zero?
 beq rts ; -Yes, sqrt(0) = 0.
 bit FACSGN ; -No, is argument negative?
 bpl :ok ; -No, go ahead.
 jmp IQERR ; -Yes, Illegal Quantity!
:ok lda FAC ; Divide exponent by 2
 clc  ;  for initial approximation.
 adc #$80 ; Move hi bit to C & clear it.
 ror  ; Divide by 2, restore hi bit.
 sta FAC
 bcc :even ; If exp even, no adjust,
 inc FAC ; If odd, inc exponent
 lsr FAC+1 ;  and shift it right.
 ror FAC+2
 ror FAC+3
 ror FAC+4
 ror EXTRAFAC ; (save low bit)
:even jsr MOVAF ; Move rounded FAC to ARG
 ldy #3
 ;;ldx #0 ; Zero FAC & TEMP1 mants
:clear stx FAC+1,y
 stx TEMP1+1,y
 dey
 bpl :clear
 ldy #32 ; Gen 32 bits of sqrt
 bne :start ; (always)

:loop ;;ldx TEMP1+1 ; Compare 40 bits of X
 cpx FAC+1 ;  with current sqrt.
 bne :check1
 lda TEMP1+2 ; Compare next byte
 cmp FAC+2
 bne :check
 lda TEMP1+3 ; Compare next byte
 cmp FAC+3
 bne :check
 lda TEMP1+4 ; Compare next byte
 cmp FAC+4
 bne :check
:start lda ARG+1 ; Compare final byte
 cmp #%01000000
:check txa
:check1 bcc :shift0 ; X > sqrt
 lda ARG+1 ; X <= sqrt, so subtract
 sbc #%01000000
 sta ARG+1
 lda TEMP1+4
 sbc FAC+4
 sta TEMP1+4
 lda TEMP1+3
 sbc FAC+3
 sta TEMP1+3
 lda TEMP1+2
 sbc FAC+2
 sta TEMP1+2
 txa
 sbc FAC+1
:shift0 rol32 FAC+1 ; Rotate C into sqrt
 asl32 ARG+1 ; Left shift X
 rol32 TEMP1+1
 asl32 ARG+1 ;  by 2 bits.
 rol32 TEMP1+1
 tax
 dey  ; Done?
 bne :loop ; -No, keep looping.
 ;;lda TEMP1+1 ; -Yes, compute final
 cmp FAC+1 ;   bit of sqrt
 ror EXTRAFAC ;    in FAC extension.
 rts

]offset equ sqr-entry-2 ; Offset = sqr - (entry+2)

[toc] | [prev] | [next] | [standalone]


#4753

FromAntoine Vignau <antoine.vignau@laposte.net>
Date2018-09-06 09:13 -0700
Message-ID<7628daf5-6574-47dc-8e10-6b3eee6ce2da@googlegroups.com>
In reply to#4750
nice.
is the rol32 macro missing a ]1 in the fourth rol?
av

[toc] | [prev] | [next] | [standalone]


#4754

Fromqkumba <peter.ferrie@gmail.com>
Date2018-09-06 10:33 -0700
Message-ID<fdcf6b66-b7bf-4a2c-b905-a3edd53f1d8e@googlegroups.com>
In reply to#4753
> is the rol32 macro missing a ]1 in the fourth rol?

No, it's an intentional rol of A.

[toc] | [prev] | [next] | [standalone]


#4755

FromMichael J. Mahon <mjmahon@aol.com>
Date2018-09-06 17:58 -0500
Message-ID<k8WdnahRx9-4LAzGnZ2dnUU7-X_NnZ2d@giganews.com>
In reply to#4750
qkumba <peter.ferrie@gmail.com> wrote:
> Okay, finally I returned to the SQR code.
> Here's the whole source with my changes.
> It caches the temp1 in X instead of zpage, so it shaves 7(?) cycles per iteration.

Nice time shaving.  ;-)

> To save two bytes, you could omit the "bne :start ; (always)" but it would cost 31 cycles.
> 
> **********************************************************
> *                                                        *
> *                SQR (X)  as  USR (X)                    *
> *                                                        *
> *                  Michael J. Mahon                      *
> *                   April 03, 2009                       *
> *                   Copyright 2009                       *
> *                                                        *
> *  Called by USR(X), computes square root of X using a   *
> *  direct non-restoring algorithm requiring about 5.2    *
> *  milliseconds on a 1MHz processor, or about nine times *
> *  faster than the Applesoft SQR function.               *
> *                                                        *
> *  USR.SQR is location-independent, and so may be BRUN   *
> *  at any location to install it as the USR function.    *
> *                                                        *
> **********************************************************
> 
> * Applesoft Page Zero Definitions
> 
> USR equ $0A ; JMP to USR function
> FAC equ $9D ; Floating-Point Accumulator
> FACSGN equ FAC+5 ; FAC unpacked sign
> EXTRAFAC equ $AC ; FAC guard byte
> TEMP1 equ $93 ; Temp FP storage
> ARG equ $A5 ; Aux FAC
> 
> * Apple ROM routines
> 
> IQERR equ $E199 ; "Illegal Quantity Error"
> MOVAF equ $EB63 ; Move rounded FAC to ARG
> IORTS equ $FF58 ; Location of RTS
> 
> * Macro Definitions
> 
> rol32 mac  ; Rotate 32 bit int left
>  rol ]1+3
>  rol ]1+2
>  rol ]1+1
>  rol
>  eom
> 
> asl32 mac  ; Shift 32 bit int left
>  asl ]1+3
>  rol ]1+2
>  rol ]1+1
>  rol ]1
>  eom
>  pag
>  org $310
> 
> * Set up USR jump to go to sqr
> 
> entry jsr IORTS ; Get entry+2 on stack
>  tsx
>  clc
>  ldaa $100-1,x ; Lo byte of entry+2
>  adc #<]offset ; Lo byte of sqr
>  sta USR+1
>  ldaa $100,x ; Hi byte of entry+2
>  adc #>]offset ; Hi byte of sqr
>  sta USR+2
> rts rts
>  pag
> * Square Root function
> 
> sqr lda FAC ; Is FAC zero?
>  beq rts ; -Yes, sqrt(0) = 0.
>  bit FACSGN ; -No, is argument negative?
>  bpl :ok ; -No, go ahead.
>  jmp IQERR ; -Yes, Illegal Quantity!
> :ok lda FAC ; Divide exponent by 2
>  clc  ;  for initial approximation.
>  adc #$80 ; Move hi bit to C & clear it.
>  ror  ; Divide by 2, restore hi bit.
>  sta FAC
>  bcc :even ; If exp even, no adjust,
>  inc FAC ; If odd, inc exponent
>  lsr FAC+1 ;  and shift it right.
>  ror FAC+2
>  ror FAC+3
>  ror FAC+4
>  ror EXTRAFAC ; (save low bit)
> :even jsr MOVAF ; Move rounded FAC to ARG
>  ldy #3
>  ;;ldx #0 ; Zero FAC & TEMP1 mants
> :clear stx FAC+1,y
>  stx TEMP1+1,y
>  dey
>  bpl :clear
>  ldy #32 ; Gen 32 bits of sqrt
>  bne :start ; (always)
> 
> :loop ;;ldx TEMP1+1 ; Compare 40 bits of X
>  cpx FAC+1 ;  with current sqrt.
>  bne :check1
>  lda TEMP1+2 ; Compare next byte
>  cmp FAC+2
>  bne :check
>  lda TEMP1+3 ; Compare next byte
>  cmp FAC+3
>  bne :check
>  lda TEMP1+4 ; Compare next byte
>  cmp FAC+4
>  bne :check
> :start lda ARG+1 ; Compare final byte
>  cmp #%01000000
> :check txa
> :check1 bcc :shift0 ; X > sqrt
>  lda ARG+1 ; X <= sqrt, so subtract
>  sbc #%01000000
>  sta ARG+1
>  lda TEMP1+4
>  sbc FAC+4
>  sta TEMP1+4
>  lda TEMP1+3
>  sbc FAC+3
>  sta TEMP1+3
>  lda TEMP1+2
>  sbc FAC+2
>  sta TEMP1+2
>  txa
>  sbc FAC+1
> :shift0 rol32 FAC+1 ; Rotate C into sqrt
>  asl32 ARG+1 ; Left shift X
>  rol32 TEMP1+1
>  asl32 ARG+1 ;  by 2 bits.
>  rol32 TEMP1+1
>  tax
>  dey  ; Done?
>  bne :loop ; -No, keep looping.
>  ;;lda TEMP1+1 ; -Yes, compute final
>  cmp FAC+1 ;   bit of sqrt
>  ror EXTRAFAC ;    in FAC extension.
>  rts
> 
> ]offset equ sqr-entry-2 ; Offset = sqr - (entry+2)
> 



-- 
-michael - NadaNet 3.1 and AppleCrate II:  http://michaeljmahon.com

[toc] | [prev] | [next] | [standalone]


#4756

FromJohn Brooks <jbrooks@blueshiftinc.com>
Date2018-09-06 22:26 -0700
Message-ID<4e02b421-dd7f-47ad-98d9-ef838dafd70d@googlegroups.com>
In reply to#2386
> I am looking for generators that are comparatively small in size, are quite fast in its algorythm and does a good job of filling the hi-res screen to white using the test program.

For things like dissolves and crossfades where each value should be visited just once, my favorite is the 16-bit shift-xor prng which got heavy use in my AppleII and GS games:

300:46 4F 66 4E 90 06 A9 B4 45 4F 85 4F 60

Here's an example program which fills the screen randomly:

 5  REM PRNG demo. J.Brooks 9/6/2018
 10  HGR2 : HCOLOR= 3: POKE 79,1
 20  FOR I = 0 TO 65535: CALL 768
 30 R =  PEEK (78) +  PEEK (79) * 256 - 1
 40 Y =  INT (R / 280):X = R - (Y * 280)
 50  IF Y < 192 THEN  HPLOT X,Y
 60  NEXT : PRINT  CHR$ (7): GET A$: TEXT


> Are there other more efficient methods for random number generation than ones mentioned here that I may have overlooked?

Below is the RND function used in many of Datasoft's Apple/Atari/C64 games that were made in the late 80s. It's not the fastest PRNG, but it's pretty small, effective, and often fast enough.

-JB
@JBrooksBSI


* DATASOFT RND 6502
* BY JAMES GARON
* 10/02/86

RNDINIT
               LDA   #$AB
               STA   RNDSEED
               LDA   #$55
               STA   RNDSEED+1
               LDA   #$7E
               STA   RNDSEED+2
               RTS

* RESULT IN ACC
RND            LDA   RNDSEED
               ROL   RNDSEED
               EOR   RNDSEED
               ROR   RNDSEED
               INC   RNDSEED+1
               BNE   RND10
               LDA   RNDSEED+2
               INC   RNDSEED+2
RND10          ADC   RNDSEED+1
               BVC   RND20
               INC   RNDSEED+1
               BNE   RND20
               LDA   RNDSEED+2
               INC   RNDSEED+2
RND20          STA   RNDSEED
               RTS

[toc] | [prev] | [next] | [standalone]


#4759

FromJohn Brooks <jbrooks@blueshiftinc.com>
Date2018-09-07 18:08 -0700
Message-ID<ea7648c0-c1a5-4712-8ad4-e866da1558ff@googlegroups.com>
In reply to#4756
On Thursday, September 6, 2018 at 10:26:10 PM UTC-7, John Brooks wrote:
> > I am looking for generators that are comparatively small in size, are quite fast in its algorythm and does a good job of filling the hi-res screen to white using the test program.
> 
> For things like dissolves and crossfades where each value should be visited just once, my favorite is the 16-bit shift-xor prng which got heavy use in my AppleII and GS games:
> 
> 300:46 4F 66 4E 90 06 A9 B4 45 4F 85 4F 60
> 
> Here's an example program which fills the screen randomly:
> 
>  5  REM PRNG demo. J.Brooks 9/6/2018
>  10  HGR2 : HCOLOR= 3: POKE 79,1
>  20  FOR I = 0 TO 65535: CALL 768
>  30 R =  PEEK (78) +  PEEK (79) * 256 - 1
>  40 Y =  INT (R / 280):X = R - (Y * 280)
>  50  IF Y < 192 THEN  HPLOT X,Y
>  60  NEXT : PRINT  CHR$ (7): GET A$: TEXT
> 
> 
> > Are there other more efficient methods for random number generation than ones mentioned here that I may have overlooked?
> 
> Below is the RND function used in many of Datasoft's Apple/Atari/C64 games that were made in the late 80s. It's not the fastest PRNG, but it's pretty small, effective, and often fast enough.
> 
> -JB
> @JBrooksBSI
> 
> 
> * DATASOFT RND 6502
> * BY JAMES GARON
> * 10/02/86
> 
> RNDINIT
>                LDA   #$AB
>                STA   RNDSEED
>                LDA   #$55
>                STA   RNDSEED+1
>                LDA   #$7E
>                STA   RNDSEED+2
>                RTS
> 
> * RESULT IN ACC
> RND            LDA   RNDSEED
>                ROL   RNDSEED
>                EOR   RNDSEED
>                ROR   RNDSEED
>                INC   RNDSEED+1
>                BNE   RND10
>                LDA   RNDSEED+2
>                INC   RNDSEED+2
> RND10          ADC   RNDSEED+1
>                BVC   RND20
>                INC   RNDSEED+1
>                BNE   RND20
>                LDA   RNDSEED+2
>                INC   RNDSEED+2
> RND20          STA   RNDSEED
>                RTS

Smaller 12-byte version of the 16-bit shift-xor PRNG:

300:A5 4F 4A 66 4E 90 02 49 B4 85 4F 60

Returns $4E=RndL, $4F(& acc)=RndH

-JB
@JBrooksBSI

[toc] | [prev] | [next] | [standalone]


#4760

FromJohn Brooks <jbrooks@blueshiftinc.com>
Date2018-09-07 18:11 -0700
Message-ID<5f960b86-8487-469a-ab16-c314f3cf93be@googlegroups.com>
In reply to#4756
On Thursday, September 6, 2018 at 10:26:10 PM UTC-7, John Brooks wrote:
> > I am looking for generators that are comparatively small in size, are quite fast in its algorythm and does a good job of filling the hi-res screen to white using the test program.
> 
> For things like dissolves and crossfades where each value should be visited just once, my favorite is the 16-bit shift-xor prng which got heavy use in my AppleII and GS games:
> 
> 300:46 4F 66 4E 90 06 A9 B4 45 4F 85 4F 60
> 
> Here's an example program which fills the screen randomly:
> 
>  5  REM PRNG demo. J.Brooks 9/6/2018
>  10  HGR2 : HCOLOR= 3: POKE 79,1
>  20  FOR I = 0 TO 65535: CALL 768
>  30 R =  PEEK (78) +  PEEK (79) * 256 - 1
>  40 Y =  INT (R / 280):X = R - (Y * 280)
>  50  IF Y < 192 THEN  HPLOT X,Y
>  60  NEXT : PRINT  CHR$ (7): GET A$: TEXT
> 
> 
> > Are there other more efficient methods for random number generation than ones mentioned here that I may have overlooked?
> 
> Below is the RND function used in many of Datasoft's Apple/Atari/C64 games that were made in the late 80s. It's not the fastest PRNG, but it's pretty small, effective, and often fast enough.
> 
> -JB
> @JBrooksBSI
> 
> 
> * DATASOFT RND 6502
> * BY JAMES GARON
> * 10/02/86
> 
> RNDINIT
>                LDA   #$AB
>                STA   RNDSEED
>                LDA   #$55
>                STA   RNDSEED+1
>                LDA   #$7E
>                STA   RNDSEED+2
>                RTS
> 
> * RESULT IN ACC
> RND            LDA   RNDSEED
>                ROL   RNDSEED
>                EOR   RNDSEED
>                ROR   RNDSEED
>                INC   RNDSEED+1
>                BNE   RND10
>                LDA   RNDSEED+2
>                INC   RNDSEED+2
> RND10          ADC   RNDSEED+1
>                BVC   RND20
>                INC   RNDSEED+1
>                BNE   RND20
>                LDA   RNDSEED+2
>                INC   RNDSEED+2
> RND20          STA   RNDSEED
>                RTS

Smaller 12-byte version of the 16-bit shift-xor PRNG: 

300:A5 4F 4A 66 4E 90 02 49 B4 85 4F 60 

Returns $4E=RndL, $4F(& acc)=RndH 

-JB 
@JBrooksBSI

[toc] | [prev] | [next] | [standalone]


#4788

Fromthe.ertceps@gmail.com
Date2018-09-29 05:03 -0700
Message-ID<fbecc8a9-c5a1-4248-a578-77c6fbc77461@googlegroups.com>
In reply to#2386
depending on what you're doing and how intensive it it, I read on a machine that had no practical way of producing random numbers, was to simply have it sit there count from 1-... and when you need a number you pull it out of the loop.  In the original case it counted while waiting for input.  But it could be adapted to other uses.

[toc] | [prev] | [next] | [standalone]


#4789

FromJames Davis <JPD.Enterprises@outlook.com>
Date2018-09-29 10:24 -0700
Message-ID<d924c2c5-1853-4111-b309-d94a597db6de@googlegroups.com>
In reply to#4788
On Saturday, September 29, 2018 at 5:03:12 AM UTC-7, Anthony Adverse wrote:
> depending on what you're doing and how intensive it it, I read on a machine that had no practical way of producing random numbers, was to simply have it sit there count from 1-... and when you need a number you pull it out of the loop.  In the original case it counted while waiting for input.  But it could be adapted to other uses.

Doesn't something similar for generating random numbers occur in the Apple II monitor?

[toc] | [prev] | [next] | [standalone]


#4790

FromMarco Verpelli <mverpelli@libero.it>
Date2018-09-29 10:30 -0700
Message-ID<501a2f57-19fd-4ddf-8888-f736a67f58a7@googlegroups.com>
In reply to#4789
On Saturday, September 29, 2018 at 7:24:44 PM UTC+2, James Davis wrote:
> On Saturday, September 29, 2018 at 5:03:12 AM UTC-7, Anthony Adverse wrote:
> > depending on what you're doing and how intensive it it, I read on a machine that had no practical way of producing random numbers, was to simply have it sit there count from 1-... and when you need a number you pull it out of the loop.  In the original case it counted while waiting for input.  But it could be adapted to other uses.
> 
> Doesn't something similar for generating random numbers occur in the Apple II monitor?

A counter is incremented while waiting for a key pressed

Marco

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.sys.apple2.programmer


csiph-web