| ------------------------------------------------------------------------ | Utilities | ------------------------------------------------------------------------ .include "macros.inc" | Random number generator | ------------------------------------------------------------------------ | Seed random number generator, using a 32 bit seed stored in d0 (s0s1s2s3 high | to low bytes) This needn't be a pseudoroutine, but just for symmetry with the | following routine, we'll make it one .text rng_seed: move.b %d0, %d4 lsr.l #8, %d0 move.b %d0, %d5 lsr.l #8, %d0 move.b %d0, %d6 lsr.l #8, %d0 move.b %d0, %d7 pseudo_ret | Reverse of seed: it will collect the seed from registers d4-d7 to d0 rng_unseed: move.b %d7, %d0 lsl.l #8, %d0 move.b %d6, %d0 lsl.l #8, %d0 move.b %d5, %d0 lsl.l #8, %d0 move.b %d4, %d0 lsl.l #8, %d0 pseudo_ret | Calculate next random number, it will be stored in the low byte of d7 rng_calc_next: add.l #1, %d4 eor.b %d7, %d5 eor.b %d4, %d5 add.b %d5, %d6 lsl.w #8, %d4 | Hack - shift d4 to the left, so we can use its 8 LSB for storing the intermediate value move.b %d6, %d4 | - Tmp store d6 lsr.b #1, %d4 | - This will produce d6>>1 in the LSB add.b %d4, %d7 | Yup! I remebered it! lsr.w #8, %d4 | Hack - Revert d4 to what it was before eor.b %d5, %d7 pseudo_ret | Function exposed to C - 1 longword argument .global rng_next rng_next: link %fp, #0 movem %d2-%d7/%a2-%a5, -(%sp) move.l 8(%fp), %d0 pseudo_call rng_seed pseudo_call rng_calc_next pseudo_call rng_unseed movem (%sp)+, %d2-%d7/%a2-%a5 unlk %fp rts