123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- ; RANDOM functions
- ;
- #include once <mul32.asm>
- ;
- RANDOMIZE:
- ; Randomize with 32 bit seed in DE HL
- ; if SEED = 0, calls ROM to take frames as seed
- ;- PROC
- ;- LOCAL TAKE_FRAMES
- ;- LOCAL FRAMES
- ;- ld a, h
- ora z80_l ;- or l
- ora z80_d ;- or d
- ora z80_e ;- or e
- ;- jr z, TAKE_FRAMES
- ;- ld (RANDOM_SEED_LOW), hl
- ;- ld (RANDOM_SEED_HIGH), de
- rts ;- ret
- TAKE_FRAMES:
- ; Takes the seed from frames
- ;- ld hl, (FRAMES)
- ;- ld (RANDOM_SEED_LOW), hl
- ;- ld hl, (FRAMES + 2)
- ;- ld (RANDOM_SEED_HIGH), hl
- rts ;- ret
- FRAMES EQU 23672
- ;- ENDP
- RANDOM_SEED_HIGH EQU RAND+6 ; RANDOM seed, 16 higher bits
- RANDOM_SEED_LOW EQU 23670 ; RANDOM seed, 16 lower bits
- RAND:
- ;- PROC
- ;- LOCAL RAND_LOOP
- ;- ld b, 4
- RAND_LOOP:
- ;- ld hl,(RANDOM_SEED_LOW) ; xz -> yw
- ;- ld de,0C0DEh ; yw -> zt
- ;- ld (RANDOM_SEED_LOW),de ; x = y, z = w
- ;- ld a,e ; w = w ^ ( w << 3 )
- ;- add a,a
- ;- add a,a
- ;- add a,a
- eor z80_e ;- xor e
- ;- ld e,a
- ;- ld a,h ; t = x ^ (x << 1)
- ;- add a,a
- eor z80_h ;- xor h
- ;- ld d,a
- ;- rra ; t = t ^ (t >> 1) ^ w
- eor z80_d ;- xor d
- eor z80_e ;- xor e
- ;- ld h,l ; y = z
- ;- ld l,a ; w = t
- ;- ld (RANDOM_SEED_HIGH),hl
- pha ;- push af
- php
- ;- djnz RAND_LOOP
- plp ;- pop af
- pha
- plp ;- pop af
- pha
- lda z80_a ;- ld d,a
- sta z80_d
- plp ;- pop af
- pha
- lda z80_a ;- ld e,a
- sta z80_e
- plp ;- pop af
- pha
- lda z80_a ;- ld h,a
- sta z80_h
- rts ;- ret
- ;- ENDP
- RND:
- ; Returns a FLOATING point integer
- ; using RAND as a mantissa
- ;- PROC
- ;- LOCAL RND_LOOP
- jsr RAND ;- call RAND
- ; BC = HL since ZX BASIC uses ED CB A registers for FP
- lda z80_h ;- ld b,h
- sta z80_b
- lda z80_l ;- ld c,l
- sta z80_c
- lda z80_e ;- ld a,e
- sta z80_a
- ora z80_d ;- or d
- ora z80_c ;- or c
- ora z80_b ;- or b
- bne *+3 ;- ret z ; Returns 0 if BC=DE=0
- rts
- ; We already have a random 32 bit mantissa in ED CB
- ; From 0001h to FFFFh
- ;- ld l,81h ; Exponent
- ; At this point we have [0 .. 1) FP number;
- ; Now we must shift mantissa left until highest bit goes into carry
- ;- ld a, e ; Use A register for rotating E faster (using RLA instead of RL E)
- RND_LOOP:
- ;- dec l
- ;- sla b
- rol z80_c ;- rl c
- rol z80_d ;- rl d
- ;- rla
- jcs RND_LOOP ;- jp nc, RND_LOOP
- ; Now undo last mantissa left-shift once
- ;- ccf ; Clears carry to insert a 0 bit back into mantissa -> positive FP number
- ;- rra
- ror z80_d ;- rr d
- ror z80_c ;- rr c
- ror z80_b ;- rr b
- lda z80_a ;- ld e,a ; E must have the highest byte
- sta z80_e
- lda z80_l ;- ld a,l ; exponent in A
- sta z80_a
- rts ;- ret
- ;- ENDP
|