dmgtris/src/rng.asm

139 lines
1.9 KiB
NASM

IF !DEF(RNG_ASM)
DEF RNG_ASM EQU 1
INCLUDE "globals.asm"
SECTION "RNG Variables", WRAM0
wRNGSeed: ds 4
wPieceHistory: ds 4
wNextPiece:: ds 1
section "RNG Functions", ROM0
RNGInit::
; Do some bit fuckery on the seed using the gameboy's free-running timers.
ld hl, wRNGSeed
ldh a, [rDIV]
xor a, [hl]
ld [hl+], a
ldh a, [rTIMA]
xor a, [hl]
ld [hl+], a
ldh a, [rDIV]
xor a, [hl]
ld [hl+], a
ldh a, [rTIMA]
xor a, [hl]
ld [hl], a
; Initialize the next history.
ld hl, wPieceHistory
ld a, PIECE_Z
ld [hl+], a
ld [hl+], a
ld a, PIECE_S
ld [hl+], a
ld [hl], a
; Get the first piece and make sure it's not Z, S or O.
: call NextPiece
cp a, PIECE_Z
jr z, :-
cp a, PIECE_S
jr z, :-
cp a, PIECE_O
jr z, :-
; Store it.
ld hl, wPieceHistory
ld [hl], a
ld hl, wNextPiece
ld [hl], a
ret
GetNextPiece::
ld e, 7
: dec e
jr z, :+
call NextPiece
ld hl, wPieceHistory
cp a, [hl]
jr z, :-
inc hl
cp a, [hl]
jr z, :-
inc hl
cp a, [hl]
jr z, :-
inc hl
cp a, [hl]
jr z, :-
: ld hl, wNextPiece
ld [hl], a
ld b, a
ld hl, wPieceHistory+2
ld a, [hl+]
ld [hl], a
ld hl, wPieceHistory+1
ld a, [hl+]
ld [hl], a
ld hl, wPieceHistory
ld a, [hl+]
ld [hl-], a
ld a, b
ld [hl], a
ret
NextPiece:
call NextByte
and a, $07
cp a, 7
ret nz
dec a
ret
NextByte:
; Load seed
ld hl,wRNGSeed+3
ld a, [hl-]
ld b, a
ld a, [hl-]
ld c, a
ld a, [hl-]
; Multiply by 0x01010101
add [hl]
ld d, a
adc c
ld c, a
adc b
ld b, a
; Add 0x31415927 and write back
ld a, [hl]
add $27
ld [hl+], a
ld a, d
adc $59
ld [hl+], a
ld a, c
adc $41
ld [hl+], a
ld c, a
ld a, b
adc $31
ld [hl], a
ret
ENDC