Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; This code was originally found in Prism. Originally written on 2016-12-18; updated on 2018-08-18 with a bug fix.
- ; Since I never bothered with a license header, I'm hereby placing it in the public domain as of 2019-01-04.
- StableRandom::
- ; in: hl: pointer to 8-byte RNG state
- ; out: a: random value; other registers preserved
- push bc
- push de
- push hl
- call .advance_left_register
- call .check_right_register_cycles
- call .advance_right_register
- inc hl
- inc hl
- inc hl
- call .advance_selector_register
- pop hl
- push hl
- rlca
- rlca
- ld c, a
- and 3
- ld e, a
- ld d, 0
- add hl, de
- ld b, [hl]
- pop hl
- push hl
- ld e, 5
- add hl, de
- ld a, c
- ld c, [hl]
- rlca
- rlca
- and 3
- call .combine_register_values
- pop hl
- pop de
- pop bc
- ret
- .advance_left_register
- ; in: hl: pointer to left register
- ; out: hl: pointer to RIGHT register
- ld a, [hli]
- ld e, a
- ld a, [hli]
- ld d, a
- ld a, [hli]
- ld c, a
- ld a, [hld]
- ld b, a
- or c
- or d
- or e
- call z, .reseed_left_register
- ld a, e
- xor d
- ld e, a
- ld a, d
- xor c
- ld d, a
- ld a, c
- xor b
- ld c, a
- ld a, c
- ld [hld], a
- ld a, d
- ld [hld], a
- ld [hl], e
- sla e
- rl d
- rl c
- inc hl
- ld a, [hl]
- xor e
- ld [hli], a
- ld a, [hl]
- xor d
- ld [hli], a
- ld a, [hl]
- xor c
- ld [hld], a
- ld b, a
- ld c, [hl]
- sla c
- rl b
- sbc a
- and 1
- dec hl
- xor [hl]
- ld [hld], a
- ld a, [hl]
- xor b
- ld [hli], a
- inc hl
- inc hl
- inc hl
- ret
- .reseed_left_register
- ; in: hl: pointer to left register + 2
- ; out: hl preserved; bcde new seed
- ld de, 5
- push hl
- add hl, de
- call .advance_selector_register
- ld b, a
- call .advance_selector_register
- ld c, a
- call .advance_selector_register
- ld d, a
- call .advance_selector_register
- ld e, a
- pop hl
- inc hl
- ld a, b
- ld [hld], a ;only b needs to be written back, since the rest will be handled by the main function
- ret
- .check_right_register_cycles
- ; in: hl: pointer to right register
- ; out: hl preserved
- inc hl
- inc hl
- ld a, [hld]
- ld c, a
- ld a, [hld]
- ld d, a
- or c
- ld e, [hl]
- push hl
- jr z, .check_long_cycles
- ld hl, .right_register_short_cycles - 1
- ld b, (.right_register_short_cycles_end - .right_register_short_cycles) / 3 + 1
- .short_cycle_handle_loop
- inc hl
- dec b
- jr z, .pop_ret
- .short_cycle_loop
- ld a, [hli]
- cp c
- ld a, [hli]
- jr nz, .short_cycle_handle_loop
- cp d
- jr nz, .short_cycle_handle_loop
- ld a, e
- cp [hl]
- jr nz, .short_cycle_handle_loop
- inc hl
- .copy_right_register_state
- ld a, [hli]
- ld c, a
- ld a, [hli]
- ld b, [hl]
- pop hl
- inc hl
- ld [hli], a
- ld a, c
- ld [hld], a
- dec hl
- ld [hl], b
- ret
- .check_long_cycles
- ld hl, .right_register_long_cycles
- .long_cycle_loop
- ld a, [hli]
- and a
- jr z, .pop_ret
- cp e
- jr nz, .long_cycle_loop
- ld a, [hl]
- and a
- jr z, .start_short_cycles
- pop hl
- ld [hl], a
- ret
- .start_short_cycles
- pop hl
- push hl
- inc hl
- inc hl
- inc hl
- call .advance_selector_register
- ld hl, .right_register_short_cycles
- jr .copy_right_register_state
- .pop_ret
- pop hl
- ret
- .right_register_short_cycles
- db $72, $4f, $9f
- db $7b, $1a, $7b
- db $84, $e5, $56
- db $8d, $b0, $32
- .right_register_short_cycles_end
- db 0, 0
- .right_register_long_cycles
- db 1, 2, 4, 8, 13, 17, 23, 26, 29, 58
- db 0
- .advance_right_register
- ; in: hl: pointer to right register
- ; out: hl preserved
- ld a, [hli]
- cp 210
- jr c, .right_carry_OK
- sub 210
- .right_carry_OK
- ld d, a
- ld a, [hli]
- ld e, a
- ld c, [hl]
- or c
- or d
- jr z, .right_register_needs_reseed
- ld a, c
- and e
- inc a
- jr nz, .right_register_OK
- ld a, d
- cp 209
- jr nz, .right_register_OK
- .right_register_needs_reseed
- call .reseed_right_register
- .right_register_OK
- ld a, e
- ld [hld], a
- push hl
- ld b, 0
- ld h, b
- ld l, d
- ld a, 210
- rst AddNTimes
- ld a, l
- ld b, h
- pop hl
- ld [hld], a
- ld [hl], b
- ret
- .reseed_right_register
- ; in: hl: pointer to right register + 2
- ; out: hl preserved, cde new seed
- inc hl
- call .advance_selector_register
- ld c, a
- call .advance_selector_register
- ld d, a
- sub 210
- jr c, .carry_reseed_OK
- ld d, a
- .carry_reseed_OK
- call .advance_selector_register
- ld e, a
- dec hl
- ret
- .advance_selector_register
- ; in: hl: pointer to selector register
- ; out: all registers but a preserved; a = new selector
- push bc
- ld a, [hl]
- ld b, 0
- rra
- rr b
- rra
- rr b
- ld a, [hl]
- swap a
- rrca
- and $f8
- add a, b
- add a, [hl]
- add a, 29
- ld [hl], a
- pop bc
- ret
- .combine_register_values
- and a
- jr z, .add_registers
- dec a
- jr z, .xor_registers
- dec a
- jr z, .subtract_registers
- ld a, c
- sub b
- ret
- .subtract_registers
- ld a, b
- sub c
- ret
- .add_registers
- ld a, b
- add a, c
- ret
- .xor_registers
- ld a, b
- xor c
- ret
RAW Paste Data
Copied