root/src/dps8/bsd_random.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bsd_srandom
  2. bsd_initstate
  3. bsd_setstate
  4. bsd_random

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: BSD-3-Clause
   4  * scspell-id: ecbb6700-f62c-11ec-a713-80ee73e9b8e7
   5  *
   6  * ---------------------------------------------------------------------------
   7  *
   8  * Copyright (c) 1983-1991 Regents of the University of California
   9  * Copyright (c) 2021-2023 The DPS8M Development Team
  10  *
  11  * All rights reserved.
  12  *
  13  * Redistribution and use in source and binary forms, with or without
  14  * modification, are permitted provided that the following conditions
  15  * are met:
  16  *
  17  * 1. Redistributions of source code must retain the above copyright
  18  *    notice, this list of conditions and the following disclaimer.
  19  *
  20  * 2. Redistributions in binary form must reproduce the above copyright
  21  *    notice, this list of conditions and the following disclaimer in the
  22  *    documentation and/or other materials provided with the distribution.
  23  *
  24  * 3. Neither the name of the University nor the names of its contributors
  25  *    may be used to endorse or promote products derived from this software
  26  *    without specific prior written permission.
  27  *
  28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  38  * SUCH DAMAGE.
  39  *
  40  * ---------------------------------------------------------------------------
  41  */
  42 
  43 #if defined( __MINGW64__ ) || defined( __MINGW32__ )
  44 
  45 # include <stdio.h>
  46 
  47 # include "bsd_random.h"
  48 
  49 # define TYPE_0    0
  50 # define BREAK_0   8
  51 # define DEG_0     0
  52 # define SEP_0     0
  53 
  54 # define TYPE_1    1
  55 # define BREAK_1   32
  56 # define DEG_1     7
  57 # define SEP_1     3
  58 
  59 # define TYPE_2    2
  60 # define BREAK_2   64
  61 # define DEG_2     15
  62 # define SEP_2     1
  63 
  64 # define TYPE_3    3
  65 # define BREAK_3   128
  66 # define DEG_3     31
  67 # define SEP_3     3
  68 
  69 # define TYPE_4    4
  70 # define BREAK_4   256
  71 # define DEG_4     63
  72 # define SEP_4     1
  73 
  74 # define MAX_TYPES 5
  75 
  76 static int degrees[MAX_TYPES] = {
  77   DEG_0, DEG_1, DEG_2, DEG_3, DEG_4
  78 };
  79 
  80 static int seps[MAX_TYPES] = {
  81   SEP_0, SEP_1, SEP_2, SEP_3, SEP_4
  82 };
  83 
  84 static long randtbl[DEG_3 + 1] = {
  85   TYPE_3,     0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0,
  86   0xdf0a6fb5, 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918,
  87   0x946554fd, 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a,
  88   0x1588ca88, 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96,
  89   0xac94efdc, 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e,
  90   0x8999220b, 0x27fb47b9,
  91 };
  92 
  93 static long *fptr     = &randtbl[SEP_3 + 1];
  94 static long *rptr     = &randtbl[1];
  95 static long *state    = &randtbl[1];
  96 static int  rand_type = TYPE_3;
  97 static int  rand_deg  = DEG_3;
  98 static int  rand_sep  = SEP_3;
  99 static long *end_ptr  = &randtbl[DEG_3 + 1];
 100 
 101 void
 102 bsd_srandom(unsigned int x)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104   if (rand_type == TYPE_0)
 105     {
 106       state[0] = x;
 107     }
 108   else
 109     {
 110       register int i;
 111       state[0] = x;
 112       for (i = 1; i < rand_deg; i++)
 113         {
 114           state[i] = 1103515245 * state[i - 1] + 12345;
 115         }
 116 
 117       fptr = &state[rand_sep];
 118       rptr = &state[0];
 119       for (i = 0; i < 10 * rand_deg; i++)
 120         {
 121           (void)bsd_random();
 122         }
 123     }
 124 }
 125 
 126 char *
 127 bsd_initstate(unsigned int seed, char *arg_state, int n)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129   register char *ostate = (char *)( &state[-1] );
 130 
 131   if (rand_type == TYPE_0)
 132     {
 133       state[-1] = rand_type;
 134     }
 135   else
 136     {
 137       state[-1] = MAX_TYPES * ( rptr - state ) + rand_type;
 138     }
 139 
 140   if (n < BREAK_0)
 141     {
 142       return 0;
 143     }
 144 
 145   if (n < BREAK_1)
 146     {
 147       rand_type = TYPE_0;
 148       rand_deg  = DEG_0;
 149       rand_sep  = SEP_0;
 150     }
 151   else if (n < BREAK_2)
 152     {
 153       rand_type = TYPE_1;
 154       rand_deg  = DEG_1;
 155       rand_sep  = SEP_1;
 156     }
 157   else if (n < BREAK_3)
 158     {
 159       rand_type = TYPE_2;
 160       rand_deg  = DEG_2;
 161       rand_sep  = SEP_2;
 162     }
 163   else if (n < BREAK_4)
 164     {
 165       rand_type = TYPE_3;
 166       rand_deg  = DEG_3;
 167       rand_sep  = SEP_3;
 168     }
 169   else
 170     {
 171       rand_type = TYPE_4;
 172       rand_deg  = DEG_4;
 173       rand_sep  = SEP_4;
 174     }
 175 
 176   state   = &(((long *)arg_state )[1] );
 177   end_ptr = &state[rand_deg];
 178   bsd_srandom(seed);
 179   if (rand_type == TYPE_0)
 180     {
 181       state[-1] = rand_type;
 182     }
 183   else
 184     {
 185       state[-1] = MAX_TYPES * ( rptr - state ) + rand_type;
 186     }
 187 
 188   return ostate;
 189 }
 190 
 191 char *
 192 bsd_setstate(char *arg_state)
     /* [previous][next][first][last][top][bottom][index][help] */
 193 {
 194   register long *new_state = (long *)arg_state;
 195   register int type        = (int)( new_state[0] % MAX_TYPES );
 196   register int rear        = (int)( new_state[0] / MAX_TYPES );
 197   char *ostate             = (char *)( &state[-1] );
 198 
 199   if (rand_type == TYPE_0)
 200     {
 201       state[-1] = rand_type;
 202     }
 203   else
 204     {
 205       state[-1] = MAX_TYPES * ( rptr - state ) + rand_type;
 206     }
 207 
 208   switch (type)
 209     {
 210     case TYPE_0:
 211     case TYPE_1:
 212     case TYPE_2:
 213     case TYPE_3:
 214     case TYPE_4:
 215       rand_type = type;
 216       rand_deg  = degrees[type];
 217       rand_sep  = seps[type];
 218       break;
 219     }
 220 
 221   state = &new_state[1];
 222   if (rand_type != TYPE_0)
 223     {
 224       rptr = &state[rear];
 225       fptr = &state[( rear + rand_sep ) % rand_deg];
 226     }
 227 
 228   end_ptr = &state[rand_deg];
 229   return ostate;
 230 }
 231 
 232 long
 233 bsd_random(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 234 {
 235   long i;
 236 
 237   if (rand_type == TYPE_0)
 238     {
 239       i = state[0] = ( state[0] * 1103515245 + 12345 ) & 0x7fffffff;
 240     }
 241   else
 242     {
 243       *fptr += *rptr;
 244       i = ( *fptr >> 1 ) & 0x7fffffff;
 245       if (++fptr >= end_ptr)
 246         {
 247           fptr = state;
 248           ++rptr;
 249         }
 250       else if (++rptr >= end_ptr)
 251         {
 252           rptr = state;
 253         }
 254     }
 255 
 256   return i;
 257 }
 258 
 259 #endif /* if defined(__MINGW64__) || defined(__MINGW32__) */

/* [previous][next][first][last][top][bottom][index][help] */