(* Generating pseudo random numbers

Documentatie over schuifregisters als random generator

Schuifregister waarvan de uitgangen genummerd zijn van 1 t/m 'm'
en de uitgangen 'm' en 'n' geXORed worden en het resultaat
daarvan weer op bit 1 ingevoerd wordt.

    m   n   cyclus-lengte       woordlengte
 ---------------------------------------------
    3   2       7
    4   3       15                  4 bits
    5   3       31
    6   5       63
    7   6       127                 8 bits
    9   5       511
   10   7       1023
   11   9       2047
   15  14       32767               16 bits
   17  14       131071
   18  11       262143
   20  17       1048575
   23  18       8388607             24 bits
   31  28       2147486347          32 bits
   39  35       549755813887        40 bits

    m       n       cyclus-lengte   woordlengte
 -------------------------------------------------
    8     4,5,6         255             8 bits
   16    4,13,15        65535           16 bits
   24   17,22,23        16777215        24 bits

Als voorbeeld een generator met een (m) 7 bits cyclus.

ENDDOC

REGISTER SEED                           \ Werkplek voor random generator

CODE RANDOM     ( -- )                  \ Maak een pseudo random getal
    R16 ADR SEED MOV,                   \ met een 7 bits cyclus
    R16 LSL,
    R17 R16 MOV,
    R17 LSL,
    R16 R17 EOR,
    R16 LSL,
    ADR SEED ROL,
    RET,
END-CODE

: CHOOSE        ( u1 -- 0 to u1-1 )     \ Maak 'random' getal tussen 0 en u1-1
    RANDOM  SEED UM* NIP
    ;

                              ( Einde )

REGISTER RNDL                           \ Random work area
REGISTER RNDH

CODE RANDOM         ( -- u )            \ Rnd Make random number u
    R16 ADR RNDH MOV,
    R16 ROL,                            \ Move bit 14 to bit 15 location
    R16 ADR RNDL EOR,                   \ Xor it with bit 7 of word
    R16 ROL,                            \ Save result in carry
    ADR RNDL ROL,                       \ Shift it in at bit 0 position
    ADR RNDH ROL,                       \ Shift bit 7 to bit 8 position
    -X ADR RNDL ST,                     \ We use low byte as result
    RET,
END-CODE

\G Maak het random getal 'u2', 'u2' ligt in het bereik van 0 tot 'u1-1'.
: CHOOSE            ( u1 -- u2 )        \ Rnd Make random number u2 the
    RANDOM  UM* NIP                     \ range of u2 is 0 to u1-1
    ;

\G Initialiseer het random getal zaadje.
MACRO: SETUP-RANDOM ( -- )              \ Rnd Initialise random work location
    31414. NIP  TO RNDH
    31414. DROP TO RNDL
    ;

*)

( CHOOSE - Make pseudo random number u2 the range of u2 is 0 to u1-1 )

: /MS           0 ?do  30 0 do loop  loop ;  \ Wait u times 0,1 ms

value RND   ( Work location for pseudo random numbers )
decimal     ( Make pseudo random number ud )
: RANDOM        ( -- ud )       rnd 31421 *  6927 +  dup to rnd ;
: CHOOSE        ( u1 -- u2 )    random  um* nip ;
: SETUP-RANDOM  ( -- )          31414 to rnd ;
hex

: RFILL         ( +n -- )       \ Fill with random pattern +n columns
    40 {ol                      \ Start oled-data stream
    begin                       \ Whole screen buffer
        256 choose i2out        \ Output pattern
    1- ?dup 0= until  i2stop} ; \ End stream

: STARS         ( -- )          \ Sky with stars
    setup-random
    begin
        400 rfill 100 ms
    key? until ;

shield RANDOM\  freeze

( Einde )
