97 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| ;rand - simple random number generator
 | |
| ;requires maths.z
 | |
| ;algorithm adapted from the one I used for 8086 kirsten.
 | |
| 
 | |
| ;for cpm zmac:
 | |
| ;ZZglobal seed
 | |
| ;ZZglobal srand
 | |
| ;ZZglobal rand16
 | |
| ;ZZglobal rand
 | |
| 
 | |
| ;uses these:
 | |
| ;ZZglobal multiply
 | |
| ;ZZglobal divide
 | |
| 
 | |
| 
 | |
| seed: defb 'ZX81'	;don't ask :-)
 | |
| 
 | |
| 
 | |
| ;set random number seed from R
 | |
| ;entry: none, exit: none
 | |
| ;af/hl corrupt
 | |
| srand:
 | |
| ld a,r
 | |
| ld h,a
 | |
| ld a,r
 | |
| ld l,a
 | |
| ld (seed),hl
 | |
| ld a,r
 | |
| ld h,a
 | |
| ld a,r
 | |
| ld l,a
 | |
| ld (seed+2),hl
 | |
| ret
 | |
| 
 | |
| 
 | |
| ;get random number in range 0 to hl-1 inclusive
 | |
| ;entry:	hl=range size
 | |
| ;exit:	hl=random number in range 0 to range_size-1
 | |
| ;af/bc/de corrupt
 | |
| ;this is equivalent to 'rand()%range_size' in C; the Linux 'rand'
 | |
| ;man page suggests this alternative if you need a better distribution,
 | |
| ;which may be a good idea for numbers bigger than a few thousand:
 | |
| ;
 | |
| ; >        To  ensure  a  good distribution for a subrange of values,
 | |
| ; >        use code like the below:
 | |
| ; >             i = RAND_MAX / my_range
 | |
| ; >             i *= my_range
 | |
| ; >             while ((j = rand()) >= i) continue;
 | |
| ; >             return j % i;
 | |
| ; >        (code example based on code from Karl Lehenbauer's fortune
 | |
| ; >        cookie  program,  which  credits  Ken Arnold, Unix Review,
 | |
| ; >        October 1987).
 | |
| ;
 | |
| ;replace rand() above with a call to rand16, and RAND_MAX with FFFFh.
 | |
| ;there are multiply/divide/mod routines in maths.z. Note that using the
 | |
| ;above algorithm will be significantly slower than calling this
 | |
| ;routine, probably half the speed at best.
 | |
| rand:
 | |
| push hl
 | |
| call rand16
 | |
| pop de
 | |
| call divide
 | |
| ex de,hl
 | |
| ret
 | |
| 
 | |
| 
 | |
| 
 | |
| ;get random number between 0 and 65535 inclusive
 | |
| ;entry: none
 | |
| ;exit:	hl=random number
 | |
| ;af/bc/de corrupt
 | |
| rand16:
 | |
| ld hl,(seed+2)
 | |
| ld d,l
 | |
| add hl,hl
 | |
| add hl,hl
 | |
| ld c,h
 | |
| ld hl,(seed)
 | |
| ld b,h
 | |
| rl b
 | |
| ld e,h
 | |
| rl e
 | |
| rl d
 | |
| add hl,bc
 | |
| ld (seed),hl
 | |
| ld hl,(seed+2)
 | |
| adc hl,de
 | |
| res 7,h
 | |
| ld a,h
 | |
| and 080h
 | |
| jr nz,rand16a
 | |
| inc h
 | |
| rand16a:
 | |
| ld (seed+2),hl
 | |
| ld hl,(seed)		;now hl=16-bit rand. num.
 | |
| ret
 | 
