Code Monkey home page Code Monkey logo

prng_6502's Introduction

prng_6502

Random number generators for 6502 / NES.

Description

This is a small collection of a family of random number generators suitable for use with the NES or other 6502 CPU platforms.

Each of them implements a linear feedback shift register (LFSR) in Galois form, which is iterated 8 times to produce an 8-bit pseudo-random number.

Three widths of LFSR are provided:

  • 16-bit requires 2 bytes of state, and will repeat after 65535 numbers.
  • 24-bit requires 3 bytes, and repeats after 16777215 calls.
  • 32-bit requires 4 bytes, and repeats after 4294967295 calls.

The 16-bit version is a minimal suitable RNG for general purpose use, but if your program generates larger batches of numbers (e.g. 50 or more) it might benefit from the longer 24 or 32-bit sequences.

Usage

Initialize the zero page seed variable to any value other than 0. The size of seed is 2-4 bits, depending on the width of LFSR chosen.

Simply jsr to one of the RNG functions. An 8-bit result will be returned in the A register (with flags), and the Y register will be clobbered.

Do not mix RNGs of different width in the same program, unless you can give them each separate seed state storage. (If desired, the simple and overlapped versions can be used with the same seed state.)

The provided source code is for the CC65 assembler, but should be easily portable to other 6502 assembly dialects.

Performance

Function Width Code Size Cycles
galois16 16-bit 19 bytes 133-141 (137)
galois24 24-bit 21 bytes 173-181 (177)
galois32 32-bit 23 bytes 213-221 (217)
galois16o 16-bit 35 bytes 69
galois24o 24-bit 38 bytes 73
galois32o 32-bit 44 bytes 83

(The cycle timing includes the jsr and rts instructions.)

The simple verions of these RNG routines have the smallest code, and vary in timing by +/- 4 cycles.

The overlapped versions are slightly larger, but more than twice as fast.

In the source there are also unrolled-loop versions included for comparison, but these are all larger and slower than their overlapped counterparts.

Though there are many methods for generating pseudo-random numbers, the LFSR is chosen here because it can be done efficiently with the 6502 CPU. When iterated once per bit of output, a maximal-length LFSR is a very suitable general purpose pseudo-random number generator, with a number of desirable properties.

These LFSRs are not cryptographically secure, but this is normally an irrelevant requirement for the platform. Rigorous random number test suites such as TestU01 or PractRand may score them poorly on some tests because of this.

Notes

This research was directly prompted by jroatch who showed me an efficient 32-bit RNG implementation. My resulting 32-bit PRNG ened up being extremely similar, partly because there is really only one viable 32-bit polynomial.

The simple versions can be adapted to take Y as a parameter, rather than always generating 8 bits. If a lower number of bits is needed (e.g. a 50/50 choice only needs 1 bit), this can be used for a faster result, breaking even with the overlapped version at around 4 bits.

Though there are generally many XOR-feedback values that can generate a maximal length LFSR, the ones selected here were chosen to have as few bits as necessary, and in a compact arrangement that makes the computation faster.

  • galois16.s - 16-bit RNG implementations.
  • galois24.s - 24-bit RNG implementations.
  • galois32.s - 32-bit RNG implementations.
  • common.s - Shared state storage and variables.
  • other/ - Alternative RNG methods.
  • utils/ - Some small utility programs for investigating RNGs.
  • test.c/.cfg/.bat - A CC65 unit test for verifying the correctness of this program.

License

This code and may be used, reused, and modified for any purpose, commercial or non-commercial.

Attribution in released binaries or documentation is appreciated but not required.

If you'd like to support this project or its author, please visit: Patreon

prng_6502's People

Contributors

bbbradsmith avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.