1/*+============================================================================
  2|
  3| LEGAL
  4|
  5|     PN Version 1.0 - A Program for generating pseudonoise sequences.
  6|     Copyright (C) 1986-2024 by Sean Erik O'Connor.  All Rights Reserved.
  7|
  8|     This program is free software: you can redistribute it and/or modify
  9|     it under the terms of the GNU General Public License as published by
 10|     the Free Software Foundation, either version 3 of the License, or
 11|     (at your option) any later version.
 12|
 13|     This program is distributed in the hope that it will be useful,
 14|     but WITHOUT ANY WARRANTY; without even the implied warranty of
 15|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16|     GNU General Public License for more details.
 17|
 18|     You should have received a copy of the GNU General Public License
 19|     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 20|     
 21|     The author's address is seanerikoconnor!AT!gmail!DOT!com
 22|     with !DOT! replaced by . and the !AT! replaced by @
 23|
 24+============================================================================*/
 25
 26#include <stdio.h>
 27
 28char * legalNotice =
 29{
 30    "\n"
 31	"PN Version 1.0 - A Program for generating pseudonoise sequences.\n"
 32    "Copyright (C) 1986-2024 by Sean Erik O'Connor.  All Rights Reserved.\n"
 33    "\n"
 34    "PN comes with ABSOLUTELY NO WARRANTY; for details see the\n"
 35    "GNU General Public License.  This is free software, and you are welcome\n"
 36    "to redistribute it under certain conditions; see the GNU General Public License\n"
 37    "for details.\n\n"
 38}  ;
 39
 40int pn( void ) ;
 41
 42/* Print out values of a sample binary PN sequence. */
 43
 44int main( int argc, char * argv[] )
 45{
 46    int i ;
 47
 48    /*  Show the legal notice first.  */
 49    printf(  "%s", legalNotice )  ;
 50
 51    /* Print out PN sequence values. */
 52    for (i = 1 ;  i <= 15 ;  ++i)
 53    {
 54        printf( "pn %3d = %3d\n", i, pn() ) ;
 55    }
 56
 57    return 0 ;
 58}
 59
 60
 61/* Compute the bits of a binary PN sequence. */
 62
 63int pn( void )
 64{
 65    static unsigned int shiftRegister = 1 ;   /* Initial state of shift register, */
 66                                              /* a  = 1, a  = ... = a  = 0        */
 67                                              /*  0       1          3            */
 68
 69    unsigned int m        = 4 ;               /* Period of PN sequence = 2^m - 1 = 15   */
 70
 71    unsigned int primPoly = 0x13 ;            /* Primitive polynomial coefficients,     */
 72                                              /* x^4 + x + 1 = 10011 (binary) = 13 hex  */
 73
 74    unsigned int mask     = (1 << (m-1)) ;    /* Selects the mth bit.                   */
 75
 76    unsigned int multiplier =
 77                 (primPoly ^ (1 << m)) ;      /* Feedback multiplier, corresponding to   */
 78                                              /* the taps f ... f on the shift register, */
 79                                              /*           3     0                       */
 80                                              /* equal to the primitive polynomial       */
 81                                              /* coefficients with highest degree term   */
 82                                              /* omitted.                                */
 83
 84    unsigned int feedback ; /* Feedback bit.                  */
 85    unsigned int bit ;      /* Bit 0 or 1 of the PN sequence. */
 86    unsigned int product ;  /* Bitwise product.               */
 87    unsigned int i ;
 88
 89    product = shiftRegister & multiplier ;   /* Modulo 2 multiplication of feedback */
 90                                             /* taps times shift register contents  */
 91                                             /* in parallel.                        */
 92
 93    /* Sum up the product bits modulo 2 to get the feedback bit. */
 94    for (i = 1, feedback = 0 ;  i <= m ;  ++i)
 95    {
 96        feedback ^= (1 & product) ;         /* Add first bit of the product into  */
 97                                            /* the running sum of the feedback.   */
 98
 99        product >>= 1 ;                     /* Shift to expose next bit of the product. */
100    }
101
102    bit = shiftRegister & 1 ;               /* Save the zeroth (PN sequence) bit of */
103                                            /* of the shift register.               */
104
105    shiftRegister >>= 1 ;                   /* Shift the shift register contents.   */
106
107    if (feedback)                           /* Add feedback (if any) to the shift register */
108    {                                       /* contents.                                   */
109        shiftRegister ^= mask ;
110    }
111
112    return( bit ) ;                         /* Return the PN sequence bit. */
113}