Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/gameboy/apu/noise/noise.cpp
2 views
1
#ifdef APU_CPP
2
3
bool APU::Noise::dac_enable() {
4
return (envelope_volume || envelope_direction);
5
}
6
7
void APU::Noise::run() {
8
if(period && --period == 0) {
9
period = divisor << frequency;
10
if(frequency < 14) {
11
bool bit = (lfsr ^ (lfsr >> 1)) & 1;
12
lfsr = (lfsr >> 1) ^ (bit << (narrow_lfsr ? 6 : 14));
13
}
14
}
15
16
uint4 sample = (lfsr & 1) ? (uint4)0 : volume;
17
if(enable == false) sample = 0;
18
19
output = sample;
20
}
21
22
void APU::Noise::clock_length() {
23
if(counter && length) {
24
if(--length == 0) enable = false;
25
}
26
}
27
28
void APU::Noise::clock_envelope() {
29
if(enable && envelope_frequency && --envelope_period == 0) {
30
envelope_period = envelope_frequency;
31
if(envelope_direction == 0 && volume > 0) volume--;
32
if(envelope_direction == 1 && volume < 15) volume++;
33
}
34
}
35
36
void APU::Noise::write(unsigned r, uint8 data) {
37
if(r == 1) { //$ff20 NR41
38
length = 64 - (data & 0x3f);
39
}
40
41
if(r == 2) { //$ff21 NR42
42
envelope_volume = data >> 4;
43
envelope_direction = data & 0x08;
44
envelope_frequency = data & 0x07;
45
if(dac_enable() == false) enable = false;
46
}
47
48
if(r == 3) { //$ff22 NR43
49
frequency = data >> 4;
50
narrow_lfsr = data & 0x08;
51
divisor = (data & 0x07) << 4;
52
if(divisor == 0) divisor = 8;
53
period = divisor << frequency;
54
}
55
56
if(r == 4) { //$ff34 NR44
57
bool initialize = data & 0x80;
58
counter = data & 0x40;
59
60
if(initialize) {
61
enable = dac_enable();
62
lfsr = ~0U;
63
envelope_period = envelope_frequency;
64
volume = envelope_volume;
65
if(length == 0) length = 64;
66
}
67
}
68
}
69
70
void APU::Noise::power() {
71
enable = 0;
72
73
envelope_volume = 0;
74
envelope_direction = 0;
75
envelope_frequency = 0;
76
frequency = 0;
77
narrow_lfsr = 0;
78
divisor = 0;
79
counter = 0;
80
81
output = 0;
82
length = 0;
83
envelope_period = 0;
84
volume = 0;
85
period = 0;
86
lfsr = 0;
87
}
88
89
void APU::Noise::serialize(serializer &s) {
90
s.integer(enable);
91
92
s.integer(envelope_volume);
93
s.integer(envelope_direction);
94
s.integer(envelope_frequency);
95
s.integer(frequency);
96
s.integer(narrow_lfsr);
97
s.integer(divisor);
98
s.integer(counter);
99
100
s.integer(output);
101
s.integer(length);
102
s.integer(envelope_period);
103
s.integer(volume);
104
s.integer(period);
105
s.integer(lfsr);
106
}
107
108
#endif
109
110