gb-tarot/Random.inc

131 lines
2.4 KiB
PHP

ClockLFSR: ; uses af, bc and clocks one bit of the LFSR.
; at return time, a holds the bottom eight of lfsr state.
ldh a, [rLFSR] ;
ld b, a ; b has shifted value ; 1 cycle
srl b ; second tap is two shifts ; 2 cycles
srl b ; 2 cycles
xor a, b ; 1 cycle
srl b ; third tap iis one more shift ; 2 cycles
xor a, b ; 1 cycle
srl b ; fourth tap is two more shifts ; 2 cycles
srl b ; 2 cycles
xor a, b ; 1 cycle
and a, $1 ; now the zero flag is set iff the tap bit is 0 ; 1 cycle
; set carry flag from zero flag
scf ; 1 cycle
jr nz, .noComplementCarry ; 2 or 3 cycles
ccf ; 1 cycle if prev was 2 cycles :)
.noComplementCarry
ldh a, [rLFSR+1] ; 2 cycles
rra ; 1 cycle ; this should populate with the carry flag
ldh [rLFSR+1], a ; 2 cycles
ldh a, [rLFSR] ; 2 cycles
rra ; 1 cycle
ldh [rLFSR], a ; 2 cycles
ret ; 37 cycles total. can call roughly three of these per scanline
OneRandomByte: ; clocks LFSR 8 times so a is
call ClockLFSR
call ClockLFSR
call ClockLFSR
call ClockLFSR
call ClockLFSR
call ClockLFSR
call ClockLFSR
call ClockLFSR
ret
RandomUnderD: ; takes d as limit (inclusive)
; check what the highest bit of d is and dispatch to thee number of bits
; we're going to generate
ld d, a
ld e, %1111_1111
bit 7, d
jr nz, .inEight
ld e, %0111_1111
bit 6, d
jr nz, .inSeven
ld e, %0011_1111
bit 5, d
jr nz, .inSix
ld e, %0001_1111
bit 4, d
jr nz, .inFive
ld e, %0000_1111
bit 3, d
jr nz, .inFour
ld e, %0000_0111
bit 2, d
jr nz, .inThree
ld e, %0000_0011
bit 1, d
jr nz, .inTwo
ld e, %0000_0001
bit 0, d
jr nz, .inOne
ld a, 0
ret
.inEight
call ClockLFSR
.inSeven
call ClockLFSR
.inSix
call ClockLFSR
.inFive
call ClockLFSR
.inFour
call ClockLFSR
.inThree
call ClockLFSR
.inTwo
call ClockLFSR
.inOne
call ClockLFSR
and a, e
cp a, d
ret z
ret c
jr .inOne
SwapCards: ; takes hl as array, c and e as indices to swap (uses b and d)
inc hl ; first element of array
push hl ; save it for later
ld b, 0
ld d, 0
add hl, bc
ld a, [hl]
ld b, a ; stash old [hl+0c] in b
pop hl
push hl
add hl, de
ld a, [hl]
ld d, a ; stash old [hl+0e] in d
ld [hl], b ; put old [hl+0c] in [hl+0e]
pop hl
ld b, 0 ; return 0 to b
add hl, bc
ld [hl], d ; put old [hl+0e] in [hl+0c]
ret