Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

TextFall - a 'Matrix digital rain' style game

317 views
Skip to first unread message

ladislau szilagyi

unread,
Aug 3, 2023, 8:13:01 AM8/3/23
to
You may find-it here: https://github.com/Laci1953/RC2014-CPM/tree/main/textfall

It needs a VT100 compatible terminal

Ladislau

Mike Douglas

unread,
Aug 4, 2023, 8:57:10 AM8/4/23
to
Does this require a Z80?

ladislau szilagyi

unread,
Aug 4, 2023, 9:21:47 AM8/4/23
to
yes, it works only on Z80

bill

unread,
Aug 4, 2023, 9:55:09 AM8/4/23
to
It's written in C. Would it really be that hard to convert the two
stub assembler bits to 8080 from Z80? Unless, of course, there is
no existing 8080 C compilers left. :-)

bill

ladislau szilagyi

unread,
Aug 4, 2023, 10:04:39 AM8/4/23
to
Why not, the only obstacle would be to find a good 'set-seed-value' (_xrndseed) routine for the random number generator (rand.as) ...
The Z80 routine uses the R register.

dxforth

unread,
Aug 5, 2023, 1:02:55 AM8/5/23
to
Don't C compilers already come with reasonable RNGs? IIRC Turbo-C
used a decent LCG (not least because it had multiply). I'd be
surprised if the Z80 RNG beat it for quality. Speed without quality
is meaningless.

ladislau szilagyi

unread,
Aug 5, 2023, 3:01:51 AM8/5/23
to
Pe sâmbătă, 5 august 2023, la 08:02:55 UTC+3, dxforth a scris:

> Don't C compilers already come with reasonable RNGs? IIRC Turbo-C
> used a decent LCG (not least because it had multiply). I'd be
> surprised if the Z80 RNG beat it for quality. Speed without quality
> is meaningless.

The George Marsaglia's XOR Shift algorithm is as good as other "classic" RNG's, but much faster, and John Metcalf's assembler implementation is accurate. The "R register" based 'set-seed-value' routine is just an useful add-on from me.

Please see https://wiki.freepascal.org/Marsaglia%27s_pseudo_random_number_generators for an extended explanation.

Ladislau

Russell Marks

unread,
Aug 5, 2023, 5:43:25 PM8/5/23
to
dxforth <dxf...@gmail.com> wrote:

> Don't C compilers already come with reasonable RNGs?

Well... an old draft of the C11 standard I saw linked on Wikipedia [1]
had this memorable footnote regarding rand():

"There are no guarantees as to the quality of the random sequence
produced and some implementations are known to produce sequences with
distressingly non-random low-order bits."

I remember noticing that myself in the 90s, so I expect it was fairly
common knowledge even then.

Anyway, I believe Hitech C (presumably most relevant here) uses what I
think is the old ANSI C example implementation - though the routine
seems to date back at least as far as V7 in 1979 - multiply by
1103515245, add 12345, and return bits 30-16. From a quick look I
think lcg16of32_extended in PractRand does something very similar,
with results like this when tested:

rus@wedge:1938:/home/rus>RNG_test lcg16of32_extended
RNG_test using PractRand version 0.95
RNG = lcg16of32_extended, seed = 0xf050291b
test set = core, folding = standard (16 bit)

rng=lcg16of32_extended, seed=0xf050291b
length= 64 megabytes (2^26 bytes), time= 3.2 seconds
Test Name Raw Processed Evaluation
TMFn(2+0):wl R=+258.3 p~= 2e-148 FAIL !!!!!
TMFn(2+1):wl R=+127.4 p~= 1e-69 FAIL !!!!
[Low4/16]DC6-9x1Bytes-1 R=+109.1 p = 7.3e-63 FAIL !!!!
[Low4/16]Gap-16:A R=+220.2 p = 4.0e-173 FAIL !!!!!!
[Low4/16]Gap-16:B R=+348.2 p = 1.6e-314 FAIL !!!!!!
[Low4/16]FPF-14+6/16:all R= -7.0 p =1-1.9e-6 suspicious
[Low1/16]BCFN(2+0,13-6,T) R= +83.5 p = 5.1e-29 FAIL !!!
[Low1/16]BCFN(2+1,13-6,T) R=+132.0 p = 1.2e-45 FAIL !!!
[Low1/16]BCFN(2+2,13-6,T) R=+151.7 p = 2.2e-52 FAIL !!!!
[Low1/16]BCFN(2+3,13-6,T) R= +72.7 p = 2.5e-25 FAIL !!
[Low1/16]BCFN(2+4,13-7,T) R= +78.5 p = 3.0e-24 FAIL !!
[Low1/16]BCFN(2+5,13-8,T) R= +73.8 p = 1.1e-19 FAIL !
[Low1/16]BCFN(2+6,13-8,T) R= +42.0 p = 1.3e-11 VERY SUSPICIOUS
[Low1/16]DC6-9x1Bytes-1 R=+898.4 p = 3.1e-506 FAIL !!!!!!!
[Low1/16]Gap-16:A R= +1948 p = 2e-1567 FAIL !!!!!!!!
[Low1/16]Gap-16:B R= +2300 p = 3e-1735 FAIL !!!!!!!!
[Low1/16]FPF-14+6/16:(0,14-2) R= +78.6 p = 1.6e-68 FAIL !!!!
[Low1/16]FPF-14+6/16:(1,14-3) R= +54.8 p = 8.6e-48 FAIL !!!
[Low1/16]FPF-14+6/16:(2,14-4) R= +33.2 p = 4.4e-27 FAIL !!
[Low1/16]FPF-14+6/16:(3,14-5) R= +22.9 p = 8.3e-19 FAIL !
[Low1/16]FPF-14+6/16:(4,14-5) R= +41.5 p = 3.0e-34 FAIL !!!
[Low1/16]FPF-14+6/16:(5,14-6) R= +23.9 p = 2.3e-18 FAIL !
[Low1/16]FPF-14+6/16:(6,14-7) R= +15.3 p = 5.0e-12 VERY SUSPICIOUS
[Low1/16]FPF-14+6/16:(7,14-8) R= +17.9 p = 6.2e-13 VERY SUSPICIOUS
[Low1/16]FPF-14+6/16:(8,14-8) R= +12.3 p = 6.5e-9 very suspicious
[Low1/16]FPF-14+6/16:(9,14-9) R= +9.0 p = 5.6e-6 unusual
[Low1/16]FPF-14+6/16:(10,14-10) R= +18.1 p = 3.2e-10 very suspicious
[Low1/16]FPF-14+6/16:all R=+117.2 p = 3.6e-105 FAIL !!!!!
...and 118 test result(s) without anomalies

Perhaps it's better than a plain xorshift in some ways - I doubt I'm
the best person to make that call. But it does seem to have flaws of
its own. :-)

-Rus.

[1] From here, an interesting page in itself not least for the list of
"Parameters in common use", and I can only applaud any list which
sees fit to include the Sinclair ZX81 in that context:

https://en.wikipedia.org/wiki/Linear_congruential_generator

ladislau szilagyi

unread,
Aug 5, 2023, 11:30:09 PM8/5/23
to
Pe duminică, 6 august 2023, la 00:43:25 UTC+3, Russell Marks a scris:

>
> Perhaps it's better than a plain xorshift in some ways - I doubt I'm
> the best person to make that call. But it does seem to have flaws of
> its own. :-)
>
> -Rus.

You can check the results of a Dieharder test here: https://wiki.freepascal.org/Marsaglia%27s_pseudo_random_number_generators

XOR passes with zero failures...

Russell Marks

unread,
Aug 6, 2023, 2:50:37 PM8/6/23
to
ladislau szilagyi <ladislau...@euroqst.ro> wrote:

>Russell Marks a scris:
[...]
>> Perhaps it's better than a plain xorshift in some ways - I doubt I'm
>> the best person to make that call. But it does seem to have flaws of
>> its own. :-)

I'll just point out that "it" above = PractRand's lcg16of32_extended,
presumably indicative of Hitech C's RNG.

> You can check the results of a Dieharder test here:
> https://wiki.freepascal.org/Marsaglia%27s_pseudo_random_number_generators
>
> XOR passes with zero failures...

"The above routines are tested with FIPS-140-2 and 1000 series, which
is just indicative. A full Dieharder test for any of them can be found
on the web."

Rather than doing the just-Google-it dance, I ran Dieharder myself.
3.31.1 doesn't seem to support xorshift directly, making the above
claim a little surprising, but it does allow for raw binary input from
a separate program. So I gave that a go for the 32-bit xorshift I
think PractRand uses. [1] On a one-off test with a single seed it
failed four tests, got "WEAK" on another, and passed the rest. To me
this seems somewhat similar to the PractRand result I posted in the
other thread, if a bit less dramatic.

The 16-bit xorshift798 you seem to be using doesn't look to be
testable in Dieharder. Unless I missed something, that seems to want
everything to end up as 32-bit unsigned integers. (I think a test with
PractRand should be doable, and I might try that somewhen.)

Don't get me wrong, I think xorshift is remarkable, and even the 798
variant may be a decent choice of RNG in a relatively undemanding
context like this due to the speed. But George Marsaglia made it clear
in the original paper that the 32-bit version isn't perfect, saying
that it "will pass almost all tests of randomness, except the binary
rank test in Diehard". And note that Diehard != Dieharder, as foretold
by Bruce Willis.

Still, I don't mean to go on about this excessively (too late). I just
think it's good to be aware that there are inevitably tradeoffs being
made when you pick an RNG to use.

-Rus.

[1] C source for the input program below. Based on the 32-bit xorshift
code from the paper, allowing for the typo, and even using the
specified seed:

#include <stdio.h>
#include <unistd.h>

int main(void)
{
unsigned long y=2463534242;

if(isatty(1)) return 1;

while(1)
{
y^=(y<<13);
y^=(y>>17);
y^=(y<<5);
putchar(y&255);
putchar((y>>8)&255);
putchar((y>>16)&255);
putchar((y>>24)&255);
}

return 0; /* not reached */
}

The full results from Dieharder are below - from looking at the
source, I think the "Seed" report is misleading in this case as you
might expect:

rus@wedge:1988:/home/rus/src/misc>./rng-xorshift32-bin|dieharder -g 200 -a
#=============================================================================#
# dieharder version 3.31.1 Copyright 2003 Robert G. Brown #
#=============================================================================#
rng_name |rands/second| Seed |
stdin_input_raw| 1.18e+07 |3333036853|
#=============================================================================#
test_name |ntup| tsamples |psamples| p-value |Assessment
#=============================================================================#
diehard_birthdays| 0| 100| 100|0.53642569| PASSED
diehard_operm5| 0| 1000000| 100|0.03961164| PASSED
diehard_rank_32x32| 0| 40000| 100|0.00000000| FAILED
diehard_rank_6x8| 0| 100000| 100|0.88957108| PASSED
diehard_bitstream| 0| 2097152| 100|0.80640512| PASSED
diehard_opso| 0| 2097152| 100|0.28845085| PASSED
diehard_oqso| 0| 2097152| 100|0.75556675| PASSED
diehard_dna| 0| 2097152| 100|0.08450089| PASSED
diehard_count_1s_str| 0| 256000| 100|0.00000000| FAILED
diehard_count_1s_byt| 0| 256000| 100|0.19170438| PASSED
diehard_parking_lot| 0| 12000| 100|0.66912419| PASSED
diehard_2dsphere| 2| 8000| 100|0.98738804| PASSED
diehard_3dsphere| 3| 4000| 100|0.78948668| PASSED
diehard_squeeze| 0| 100000| 100|0.29019454| PASSED
diehard_sums| 0| 100| 100|0.54678793| PASSED
diehard_runs| 0| 100000| 100|0.46966316| PASSED
diehard_runs| 0| 100000| 100|0.31219271| PASSED
diehard_craps| 0| 200000| 100|0.24277725| PASSED
diehard_craps| 0| 200000| 100|0.54345280| PASSED
marsaglia_tsang_gcd| 0| 10000000| 100|0.07571716| PASSED
marsaglia_tsang_gcd| 0| 10000000| 100|0.24811787| PASSED
sts_monobit| 1| 100000| 100|0.43000839| PASSED
sts_runs| 2| 100000| 100|0.36578511| PASSED
sts_serial| 1| 100000| 100|0.59517001| PASSED
sts_serial| 2| 100000| 100|0.82307299| PASSED
sts_serial| 3| 100000| 100|0.65305437| PASSED
sts_serial| 3| 100000| 100|0.66190477| PASSED
sts_serial| 4| 100000| 100|0.01736061| PASSED
sts_serial| 4| 100000| 100|0.33172256| PASSED
sts_serial| 5| 100000| 100|0.24105442| PASSED
sts_serial| 5| 100000| 100|0.81024808| PASSED
sts_serial| 6| 100000| 100|0.67651036| PASSED
sts_serial| 6| 100000| 100|0.60045416| PASSED
sts_serial| 7| 100000| 100|0.38037782| PASSED
sts_serial| 7| 100000| 100|0.73726343| PASSED
sts_serial| 8| 100000| 100|0.15241107| PASSED
sts_serial| 8| 100000| 100|0.10499551| PASSED
sts_serial| 9| 100000| 100|0.91503579| PASSED
sts_serial| 9| 100000| 100|0.30793062| PASSED
sts_serial| 10| 100000| 100|0.95062526| PASSED
sts_serial| 10| 100000| 100|0.99348605| PASSED
sts_serial| 11| 100000| 100|0.80898455| PASSED
sts_serial| 11| 100000| 100|0.18821345| PASSED
sts_serial| 12| 100000| 100|0.12581860| PASSED
sts_serial| 12| 100000| 100|0.10190788| PASSED
sts_serial| 13| 100000| 100|0.76218225| PASSED
sts_serial| 13| 100000| 100|0.08648427| PASSED
sts_serial| 14| 100000| 100|0.64157666| PASSED
sts_serial| 14| 100000| 100|0.08202735| PASSED
sts_serial| 15| 100000| 100|0.98503258| PASSED
sts_serial| 15| 100000| 100|0.52435051| PASSED
sts_serial| 16| 100000| 100|0.36452283| PASSED
sts_serial| 16| 100000| 100|0.14360079| PASSED
rgb_bitdist| 1| 100000| 100|0.00000000| FAILED
rgb_bitdist| 2| 100000| 100|0.05051504| PASSED
rgb_bitdist| 3| 100000| 100|0.25614480| PASSED
rgb_bitdist| 4| 100000| 100|0.93339049| PASSED
rgb_bitdist| 5| 100000| 100|0.70521924| PASSED
rgb_bitdist| 6| 100000| 100|0.49985336| PASSED
rgb_bitdist| 7| 100000| 100|0.93150381| PASSED
rgb_bitdist| 8| 100000| 100|0.39571891| PASSED
rgb_bitdist| 9| 100000| 100|0.62507471| PASSED
rgb_bitdist| 10| 100000| 100|0.76762647| PASSED
rgb_bitdist| 11| 100000| 100|0.69622258| PASSED
rgb_bitdist| 12| 100000| 100|0.36148502| PASSED
rgb_minimum_distance| 2| 10000| 1000|0.45249550| PASSED
rgb_minimum_distance| 3| 10000| 1000|0.31583536| PASSED
rgb_minimum_distance| 4| 10000| 1000|0.52356354| PASSED
rgb_minimum_distance| 5| 10000| 1000|0.97996654| PASSED
rgb_permutations| 2| 100000| 100|0.24249630| PASSED
rgb_permutations| 3| 100000| 100|0.31169667| PASSED
rgb_permutations| 4| 100000| 100|0.99047844| PASSED
rgb_permutations| 5| 100000| 100|0.62659676| PASSED
rgb_lagged_sum| 0| 1000000| 100|0.99267780| PASSED
rgb_lagged_sum| 1| 1000000| 100|0.87053138| PASSED
rgb_lagged_sum| 2| 1000000| 100|0.73848226| PASSED
rgb_lagged_sum| 3| 1000000| 100|0.56350676| PASSED
rgb_lagged_sum| 4| 1000000| 100|0.30797005| PASSED
rgb_lagged_sum| 5| 1000000| 100|0.71846590| PASSED
rgb_lagged_sum| 6| 1000000| 100|0.30906571| PASSED
rgb_lagged_sum| 7| 1000000| 100|0.69790814| PASSED
rgb_lagged_sum| 8| 1000000| 100|0.08346459| PASSED
rgb_lagged_sum| 9| 1000000| 100|0.59641738| PASSED
rgb_lagged_sum| 10| 1000000| 100|0.96319122| PASSED
rgb_lagged_sum| 11| 1000000| 100|0.69731926| PASSED
rgb_lagged_sum| 12| 1000000| 100|0.17245619| PASSED
rgb_lagged_sum| 13| 1000000| 100|0.48650938| PASSED
rgb_lagged_sum| 14| 1000000| 100|0.06077480| PASSED
rgb_lagged_sum| 15| 1000000| 100|0.74732777| PASSED
rgb_lagged_sum| 16| 1000000| 100|0.31327041| PASSED
rgb_lagged_sum| 17| 1000000| 100|0.48794712| PASSED
rgb_lagged_sum| 18| 1000000| 100|0.91372185| PASSED
rgb_lagged_sum| 19| 1000000| 100|0.74600855| PASSED
rgb_lagged_sum| 20| 1000000| 100|0.90139504| PASSED
rgb_lagged_sum| 21| 1000000| 100|0.83379286| PASSED
rgb_lagged_sum| 22| 1000000| 100|0.98871326| PASSED
rgb_lagged_sum| 23| 1000000| 100|0.80184775| PASSED
rgb_lagged_sum| 24| 1000000| 100|0.49506663| PASSED
rgb_lagged_sum| 25| 1000000| 100|0.65978133| PASSED
rgb_lagged_sum| 26| 1000000| 100|0.78156427| PASSED
rgb_lagged_sum| 27| 1000000| 100|0.87272882| PASSED
rgb_lagged_sum| 28| 1000000| 100|0.50825448| PASSED
rgb_lagged_sum| 29| 1000000| 100|0.07029373| PASSED
rgb_lagged_sum| 30| 1000000| 100|0.11101590| PASSED
rgb_lagged_sum| 31| 1000000| 100|0.99820396| WEAK
rgb_lagged_sum| 32| 1000000| 100|0.04478764| PASSED
rgb_kstest_test| 0| 10000| 1000|0.38388239| PASSED
dab_bytedistrib| 0| 51200000| 1|0.23327842| PASSED
dab_dct| 256| 50000| 1|0.16098551| PASSED
Preparing to run test 207. ntuple = 0
dab_filltree| 32| 15000000| 1|0.56478084| PASSED
dab_filltree| 32| 15000000| 1|0.38452525| PASSED
Preparing to run test 208. ntuple = 0
dab_filltree2| 0| 5000000| 1|0.85956050| PASSED
dab_filltree2| 1| 5000000| 1|0.80044790| PASSED
Preparing to run test 209. ntuple = 0
dab_monobit2| 12| 65000000| 1|1.00000000| FAILED

ladislau szilagyi

unread,
Aug 6, 2023, 11:58:19 PM8/6/23
to
Hi Russell,

I'm a matematician, I graduated from the university, at the faculty of mathematics.

I understand wery well the complexity of (pseudo-)random number generators and the issues of checking-it.

All I wanted to underline is that, for CP/M games running on Z80, I consider the 2 byte xorshift798 the best I know, in its class of 2 byte pseudo random number generators.

Why?

Because it returns a positive pseudo random 2 byte integer (good enough for the vast majority of Z80 games I know...), it's very fast, it starts with returning a non-constant (variable) initial value (very important asset for a game...), and is 64K periodic, covering nicely all the possible values (see the results of some tests in the "Random numbers generator on Z80" thread, comparing-it with other 2 byte random number generators...).

I kept a rather "practical" approach, but, of course, we can discuss also the subtleties of random number generation algorithms and how to test them, but I think this would be a boring academic debate for the vast majority of the participants in this Google group.

regards,
Ladislau

Russell Marks

unread,
Aug 7, 2023, 8:32:17 AM8/7/23
to
ladislau szilagyi <ladislau...@euroqst.ro> wrote:

> I'm a matematician, I graduated from the university, at the faculty
> of mathematics.

Nice. I do realise that random people online can have qualifications
they might not always mention.

> I understand wery well the complexity of (pseudo-)random number
> generators and the issues of checking-it.

I see.

> All I wanted to underline is that, for CP/M games running on Z80, I
> consider the 2 byte xorshift798 the best I know, in its class of 2
> byte pseudo random number generators.

I mean, this seems like a step down from "perfect", but sure.

> Why?
>
> Because it returns a positive pseudo random 2 byte integer (good
> enough for the vast majority of Z80 games I know...), it's very fast,
> it starts with returning a non-constant (variable) initial value (very
> important asset for a game...), and is 64K periodic, covering nicely
> all the possible values (see the results of some tests in the "Random
> numbers generator on Z80" thread, comparing-it with other 2 byte
> random number generators...).

Have you ever seen it return a zero?

> I kept a rather "practical" approach, but, of course, we can discuss
> also the subtleties of random number generation algorithms and how to
> test them, but I think this would be a boring academic debate for the
> vast majority of the participants in this Google group.

I understand that in this context any half-decent RNG is likely fine.

-Rus.

ladislau szilagyi

unread,
Aug 7, 2023, 8:53:17 AM8/7/23
to
Pe luni, 7 august 2023, la 15:32:17 UTC+3, Russell Marks a scris:

> Have you ever seen it return a zero?

Yes, it does return zero.

Check again the code fragment below; when HL = 8000H, it returns zero:

ld (_xrnd+1),hl
res 7,h ;make-it positive...
ret

Russell Marks

unread,
Aug 7, 2023, 10:28:47 AM8/7/23
to
ladislau szilagyi <ladislau...@euroqst.ro> wrote:

>Russell Marks a scris:
>
>> Have you ever seen it return a zero?
>
> Yes, it does return zero.

Not in the pre-existing xorshift798 algorithm - please check what was
being referring to.

-Rus.

ladislau szilagyi

unread,
Aug 7, 2023, 10:37:50 AM8/7/23
to
I'm really sorry, but we are discussing in this thread about the TextFall game.

More exactly, about a component of my TextFall game, the rand.as file, containing my version of xorshift, listed below:

psect text

GLOBAL _xrnd, _xrndseed

_xrnd:
ld hl,1 ; seed must not be 0
ld a,h
rra
ld a,l
rra
xor h
ld h,a
ld a,l
rra
ld a,h
rra
xor l
ld l,a
xor h
ld h,a
ld (_xrnd+1),hl
res 7,h ;make-it positive...
ret

_xrndseed:
ld a,r
ld l,a
ld a,r
ld h,a
or l ; HL must be not NULL
jr nz,1f
inc hl
1:
ld (_xrnd+1),hl
ret

Russell Marks

unread,
Aug 7, 2023, 3:18:36 PM8/7/23
to
ladislau szilagyi <ladislau...@euroqst.ro> wrote:

>Russell Marks a scris:
>> ladislau szilagyi <ladislau...@euroqst.ro> wrote:
>>
>> >Russell Marks a scris:
>> >
>> >> Have you ever seen it return a zero?
>> >
>> > Yes, it does return zero.
>> Not in the pre-existing xorshift798 algorithm - please check what was
>> being [referred] to.
[...]
> I'm really sorry, but we are discussing in this thread about the
> TextFall game.

Here is the relevant context you previously removed:

"All I wanted to underline is that, for CP/M games running on Z80, I
consider the 2 byte xorshift798 the best I know, in its class of 2
byte pseudo random number generators."

That is clearly referring to the original algorithm, and so was I.

(It cannot plausibly be referring to your routine, as that cuts the
range of random numbers roughly in half, which is incompatible with
your "best I know" claim since you know of both.)

-Rus.

ladislau szilagyi

unread,
Aug 8, 2023, 12:08:22 AM8/8/23
to
Yes Russell, as always, you are right.
I wonder, how on earth are my programs working, I'm constantly wrong on something.
I must investigate this.

Russell Marks

unread,
Aug 8, 2023, 3:03:59 AM8/8/23
to
ladislau szilagyi <ladislau...@euroqst.ro> wrote:

> I wonder, how on earth are my programs working, I'm constantly wrong
> on something.
> I must investigate this.

Point taken. :-) I apologise for what has perhaps been excessive and
overly pedantic posting.

-Rus.

Mark Lawler

unread,
Aug 8, 2023, 6:58:20 PM8/8/23
to
On the Altair 8800 and IMSAI 8080 emulators I have built (highnibble and addwaterandstir) I wanted to generate random light patterns on the display for a better blinkenlights effect. Similar when I wanted to write my own textfall "matrix-like" screen display on my PDP-11 emulator (oscar's). On the Intel 8080 CP/M-based machines I use Manx Aztec C since that is what I used back in my Kapro II and 4 days. However, I could never seem to access the ran_ function out of the Manx Aztec C M.lib so I punted and stole this straight out of KIernighan & Ritchie until I could find something better:

/*
* int ran()
*
* Taken from the K&R C programming language book, page 46.
* Returns a psuedo-random integer of 0..32767. Written after
* not being able to access the ran_ function out of the Manx
* Aztec C M.Lib.
*
*/

long ran_next = 1;

int ran()
{
ran_next = ran_next * 1103515245 + 12345;
return ((unsigned)(ran_next / 65536) % 32768);
}

sran(seed)
unsigned int seed;
{
ran_next = seed;
}

Perhaps with this thread I have?

Best,
-Mark

ladislau szilagyi

unread,
Aug 8, 2023, 11:06:01 PM8/8/23
to
Hi Mark,

Interesting, the rand() and srand() from the HiTech C v3.09 library LIBC.LIB are identical with these K&R routines...

It's obvious why... we all learned C from the Brian Kernighan & Dennis Ritchie's book :)

regards,
Ladislau

dxforth

unread,
Aug 9, 2023, 12:12:08 AM8/9/23
to
IIRC early versions of Turbo-C took the modulus directly i.e.
the least random bits. Ideally one wants the highest order bits
in any reduction - which means using multiply rather than mod.



ladislau szilagyi

unread,
Aug 9, 2023, 2:19:27 PM8/9/23
to
Hi,

I published also the Z80ALL version of the game, here: https://github.com/Laci1953/Software-for-Z80ALL-retro-computer/tree/main/textfall

Ladislau

ladislau szilagyi

unread,
Sep 16, 2023, 2:43:58 AM9/16/23
to
Hi,

I just published an improved version for RC2014 (the cursor is hidden).

Ladislau

0 new messages