Skip to content

Instantly share code, notes, and snippets.

@JohnConnolly0
Created February 19, 2015 15:21
Show Gist options
  • Save JohnConnolly0/25c65425cf4f84954585 to your computer and use it in GitHub Desktop.
Save JohnConnolly0/25c65425cf4f84954585 to your computer and use it in GitHub Desktop.
Z80 Psuedo-random number generator
LD A,R ; Load the A register with the refresh register
LD L,A ; Copy register A into register L
AND %00111111 ; This masking prevents the address we are forming from accessing RAM
LD H,A ; Copy register A into register H
LD A,(HL) ; Load the pseudo-random value into A
; HOW THIS WORKS
; The refresh register in the Z80 is highly unpredictable since it is incremented every cycle.
; Because it may be at any value when this routine is called, it is very good for random numbers.
; This routine increases the randomness of the number since it forms an address based on the
; refresh counter's current status and accesses the memory at that address.
; It can also be modified to get a sixteen-bit pseudo-random number by changing line 5 to LD D,(HL)
; and adding these two lines to the end:
; INC L
; LD E,(HL)
; This routine was written for the ZX Spectrum which has a 16KB ROM. If you plan to use this routine
; on another Z80 system, change the binary value at the AND instruction. For example, if you had a
; Z80 computer with an 8KB ROM, you would change the binary value to %00011111.
@Utodev
Copy link

Utodev commented Nov 20, 2017

Hmmm... If you get R register you get a number from 0 to 255, so if you use that number to make a 16 bit number (masking the upper byte to get only ROM values) you will finally only read 256 ROM positions.

With only 256 ROM positions being read is likely that two positions have the same value, which means that value have double chance to be returned, and also that some other value has a 0% chance of being returned (as if there are two 37s, then another value, 36 for instance, must be missing).

Also, the Spectrum ROM has some not used zones, filled with 0xFF. Although i can't remember where they are right now, and it would be very bad luck, R register values above 0x3F will lead to a few consecutive ROM addresses (40 leads to 0040, 41 leads to 0041, etc.), so if you are unlucky there may be very likely the generator returns too many 255.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment