summaryrefslogtreecommitdiff
path: root/home/random.asm
blob: c532ec51b955809fc6b716ec855f544584ece8f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
GenRandom: ; 0x959
	push bc
	push de
	push hl
	ld a, [wRNGPointer]
	ld c, a
	ld b, $0 ;load ??? into c
	inc a
	cp 54 + 1 ;inc ???, if ??? is 55 do alot of subtraction and make ??? 0
	jr nz, .asm_96e
	call UpdateRNG
	xor a
	ld bc, $0000
.asm_96e
	ld [wRNGPointer], a ;place wRNGPointer + 1 back in
	ld hl, wRNGValues ;choose number generated based on wRNGPointer and all the subtraction
	add hl, bc
	ld a, [hl]
	pop hl
	pop de
	pop bc
	ret

ResetRNG: ; 0x97a
	ld a, [wRNGModulus]
	ld d, a
	ld a, $0 ; wasted instruction (debug that was never commented out?)
	; [wRNGSub] = [sRNGMod] % [wRNGModulus]
	ld a, [sRNGMod]
.modulo
	cp d
	jr c, .okay
	sub d
	jr .modulo

.okay
	ld [wRNGSub], a
	ld [wRNGSub2], a
	ld e, $1
	ld hl, .Data
	ld a, 54
.copy_prng
	push af
	ld c, [hl]
	inc hl
	ld b, $0
	push hl
	ld hl, wRNGValues
	add hl, bc
	ld [hl], e
	ld a, [wRNGSub]
	sub e
	jr nc, .next
	add d
.next
	ld e, a
	ld a, [hl]
	ld [wRNGSub], a
	pop hl
	pop af
	dec a
	jr nz, .copy_prng
	call UpdateRNG
	call UpdateRNG
	call UpdateRNG
	ld a, $0 ; wasted instruction (debug that was never commented out?)
	call GenRandom
	ld [sRNGMod], a
	ret

.Data
; offsets from wRNGValues
	db $14, $29, $07, $1c, $31, $0f, $24, $02, $17
	db $2c, $0a, $1f, $34, $12, $27, $05, $1a, $2f
	db $0d, $22, $00, $15, $2a, $08, $1d, $32, $10
	db $25, $03, $18, $2d, $0b, $20, $35, $13, $28
	db $06, $1b, $30, $0e, $23, $01, $16, $2b, $09
	db $1e, $33, $11, $26, $04, $19, $2e, $0c, $21

UpdateRNG: ; 0x9fa
; Adjusts two RNG values using wRNGModulus
	ld a, [wRNGModulus]
	ld d, a
 ; [d812] = ([d812] - 24 * [d831]) % [d810]
	ld bc, wRNGValues
	ld hl, wRNGValues + $1f
	ld e, $18
.loop
	ld a, [bc]
	sub [hl]
	jr nc, .no_carry
	add d
.no_carry
	ld [bc], a
	dec e
	jr nz, .loop
 ; [d82a] = ([d82a] - 31 * [d812]) % [d810]
	ld bc, wRNGValues + $18 ; d82a
	ld hl, wRNGValues
	ld e, $1f
.loop2
	ld a, [bc]
	sub [hl]
	jr nc, .no_carry2
	add d
.no_carry2
	ld [bc], a
	dec e
	jr nz, .loop2
	ret

RandomRange: ; 0xa21
; Random value 0 <= x < a
	push bc
	push hl
	ld c, a
	ld b, $0
	ld hl, EvensAndOdds
	add hl, bc
	ld l, [hl]
	call GenRandom
	call MultiplyAbyL_AncientEgyptian
	inc h
	srl h
	ld a, h
	pop hl
	pop bc
	ret

EvensAndOdds:
; The first 128 bytes are the first 128 even numbers starting at 0.
; The next 128 bytes are the first 128 odd numbers starting at 1.
; The (a)th element is essentially what you'd get from rlca.
x = 0
REPT 128
	db x | ((x >> 7) & 1)
x = x + 2
ENDR