From aa633544f1adf5d8521a99b1e2341168b1611c87 Mon Sep 17 00:00:00 2001
From: yury <jura@cp-lab.com>
Date: Wed, 5 Aug 2020 16:29:07 +0000
Subject: [PATCH] * Added a simple implementation of random. It is TP/Delphi
 compatible. Enabled it for 8/16 bit CPUs by default.

git-svn-id: trunk@46266 -
---
 rtl/inc/system.inc  | 50 +++++++++++++++++++++++++++++++++++++++++++++
 rtl/inc/systemh.inc |  9 ++++++++
 2 files changed, 59 insertions(+)

diff --git a/rtl/inc/system.inc b/rtl/inc/system.inc
index f4489ceb98..3723bb54d2 100644
--- a/rtl/inc/system.inc
+++ b/rtl/inc/system.inc
@@ -565,6 +565,7 @@ type
 {$endif FPC_HAS_FEATURE_RTTI}
 
 {$if defined(FPC_HAS_FEATURE_RANDOM)}
+{$ifndef FPC_USE_SIMPLE_RANDOM}
 
 { Pascal translation of https://github.com/dajobe/libmtwist }
 
@@ -749,6 +750,55 @@ begin
   random := mtwist_u32rand * (extended(1.0)/(int64(1) shl 32));
 end;
 {$endif}
+
+{$else FPC_USE_SIMPLE_RANDOM}
+
+{ A simple implementation of random. TP/Delphi compatible. }
+
+const
+  QRAN_A = 134775813;
+  QRAN_C = 1;
+
+function rand_next: cardinal;
+var
+  s: cardinal;
+begin
+  s:=RandSeed*QRAN_A+QRAN_C;
+	RandSeed:=s;
+  rand_next:=s;
+end;
+
+function random(l: word): word;
+var
+  s,ss: cardinal;
+begin
+  s:=rand_next;
+  { use 32-bit multiplications here }
+  ss:=(s shr 16)*l;
+  s:=(s and $FFFF)*l shr 16;
+  random:=(ss + s) shr 16;
+end;
+
+function random(l: longint): longint;
+begin
+  random:=int64(rand_next)*l shr 32;
+end;
+
+function random(l:int64):int64;
+begin
+  random:=random(longint(l));
+end;
+
+{$ifndef FPUNONE}
+function random: extended;
+const
+  c = 1.0/$10000/$10000;
+begin
+  random:=rand_next*c;
+end;
+{$endif}
+
+{$endif FPC_USE_SIMPLE_RANDOM}
 {$endif FPC_HAS_FEATURE_RANDOM}
 
 
diff --git a/rtl/inc/systemh.inc b/rtl/inc/systemh.inc
index 4bcf5a2e7d..8684da7e4d 100644
--- a/rtl/inc/systemh.inc
+++ b/rtl/inc/systemh.inc
@@ -382,6 +382,12 @@ Type
 {$endif CPUZ80}
 
 
+{ By default enable a simple implementation of Random for 8/16 bit CPUs }
+{$if (defined(CPU16) or defined(CPU8)) and not defined(FPC_NO_SIMPLE_RANDOM)}
+  {$define FPC_USE_SIMPLE_RANDOM}
+{$endif}
+
+
 {$if not declared(FarPointer)}
   FarPointer = Pointer;
 {$endif}
@@ -906,6 +912,9 @@ Function Align (Addr : PtrUInt; Alignment : PtrUInt) : PtrUInt;{$ifdef SYSTEMINL
 Function Align (Addr : Pointer; Alignment : PtrUInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
 
 {$ifdef FPC_HAS_FEATURE_RANDOM}
+{$ifdef FPC_USE_SIMPLE_RANDOM}
+Function  Random(l:word):word;
+{$endif FPC_USE_SIMPLE_RANDOM}
 Function  Random(l:longint):longint;
 Function  Random(l:int64):int64;
 {$ifndef FPUNONE}