Calculates next 32-bits pseudo-random number in Marsaglia’s XOR-shift 8-9-23 sequence.
u32 cpct_nextRandom_mxor_u32 (u32 seed) __z88dk_fastcall;
(4B DE:HL) *seed* | Number that the XOR-shift algorithm will use to calculate its pseudo-random follower on the sequence. |
call cpct_nextRandom_mxor_u32_asm
<u32> | Next 32-bits pseudo-random value in the sequence. |
This function implements a sequence of 32-bits values with period (2^32)-1. This means that it produces consecutive 32-bits values that do not repeat until 4.294.967.295 numbers have been generated. To do this, the function receives a 32-bit value as parameter (that should be different from 0) and returns the next 32-bit value in the sequence.
The sequence calculated by this function is based on Marsaglia’s XOR-shift generator using the tuple (8, 9, 23) whose implementation is fast on a Z80 (as suggested by Z88DK developers). The algorithm performs these 3 consecutive operations on the given number (seed):
// Tuple (8, 9, 23) for Marsaglia's XORshift algoritm // that this function applies to a given seed, to calculate next seed ^= seed << 8 seed ^= seed >> 9 seed ^= seed << 23
This operations are performed in an optimized fashion. To better understand optimizations performed and their meaning, it is important to visualize these 3 operations:
[ d ][ e ][ h ][ l ] 1) XOR [ e ][ h ][ l ] ==> Produces d', e', h' 2) XOR [ d' ][ e' ][ h' ] ==> Produces h'', l'' (Check notes on e'') 3) XOR [ h'' ][ l' ] ==> Produces d'', e'' ----------------------------------------------- Result [ d'' ][ e'' ][ h'' ][ l' ]
It is important to notice that e’’ is not calculated on operation 2. The implementation uses registers b and c as intermediate buffers and that lets us combine operations 2 & 3 in a single operation to directly calculate final value for register e, that will be e’’.
AF, BC, DE, HL
35 bytes
Case | microSecs (us) | CPU Cycles ----------------------------------------- Any | 37 | 148 -----------------------------------------