rand_single.z80 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #ifndef included_rand
  2. #define included_rand
  3. randinit:
  4. ld a,r
  5. ld hl,seedsingle0
  6. xor (hl) \ ld (hl),a \ inc hl
  7. xor (hl) \ ld (hl),a \ inc hl
  8. xor (hl) \ ld (hl),a \ inc hl
  9. xor (hl) \ ld (hl),a \ inc hl
  10. xor (hl) \ ld (hl),a \ inc hl
  11. xor (hl) \ ld (hl),a \ inc hl
  12. xor (hl) \ ld (hl),a \ inc hl
  13. or 97 ;no particular reason
  14. or (hl) \ ld (hl),a
  15. ret
  16. rand:
  17. ;Tested and passes all CAcert tests
  18. ;Uses a very simple 32-bit LCG and 32-bit LFSR
  19. ;it has a period of 18,446,744,069,414,584,320
  20. ;roughly 18.4 quintillion.
  21. ;LFSR taps: 0,2,6,7 = 11000101
  22. ;323cc
  23. ;Thanks to Runer112 for his help on optimizing the LCG and suggesting to try the much simpler LCG. On their own, the two are terrible, but together they are great.
  24. ;Uses 64 bits of state
  25. ld hl,(seedsingle0)
  26. ld de,(seedsingle0+2)
  27. ld b,h
  28. ld c,l
  29. add hl,hl \ rl e \ rl d
  30. add hl,hl \ rl e \ rl d
  31. inc l
  32. add hl,bc
  33. ld (seedsingle0),hl
  34. ld hl,(seedsingle0+2)
  35. adc hl,de
  36. ld (seedsingle0+2),hl
  37. ex de,hl
  38. ;lfsr
  39. ld hl,(seedsingle1)
  40. ld bc,(seedsingle1+2)
  41. add hl,hl \ rl c \ rl b
  42. ld (seedsingle1+2),bc
  43. sbc a,a
  44. and %11000101
  45. xor l
  46. ld l,a
  47. ld (seedsingle1),hl
  48. ex de,hl
  49. add hl,bc
  50. ret
  51. #endif