Skip to content

Commit 6d6c95b

Browse files
authored
Merge pull request #56 from YushiOMOTE/channel-4-tests
Channel 4 tests
2 parents 05f6400 + 4e2c91d commit 6d6c95b

8 files changed

+845
-43
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ Test status of [Same Suite](https://github.com/YushiOMOTE/SameSuite/tree/430ab7f
111111
* [x] `apu/div_write_trigger_10.gb`
112112
* [x] `apu/div_write_trigger_volume.gb`
113113
* [x] `apu/div_write_trigger_volume_10.gb`
114+
* [x] `apu/div_trigger_volume_10.gb`
115+
* [x] `apu/channel_4/channel_4_lfsr.gb`
116+
* [x] `apu/channel_4/channel_4_lfsr15.gb`
117+
* [x] `apu/channel_4/channel_4_lfsr_7_15.gb`
118+
* [x] `apu/channel_4/channel_4_lfsr_15_7.gb`
114119

115120
## Projects
116121

core/src/apu/noise.rs

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
use super::{dac::Dac, envelope::Envelope, frame_sequencer::Frame, length_counter::LengthCounter};
2-
use crate::clock::{ClockDivider, Timer};
2+
use crate::{
3+
clock::{ClockDivider, Timer},
4+
cpu::CPU_FREQ_HZ,
5+
};
36

47
use bitfield_struct::bitfield;
58

6-
const NOISE_FREQ_HZ: usize = 262_144;
9+
// LFSR runs at CPU rate.
10+
const NOISE_FREQ_HZ: usize = CPU_FREQ_HZ;
711

812
#[derive(Debug, Clone)]
913
pub struct Noise {
@@ -122,6 +126,7 @@ impl Noise {
122126
}
123127

124128
self.nr43 = Nr43::from_bits(value);
129+
self.lfsr.set_mode(self.nr43.step());
125130
}
126131

127132
/// Read NR44 register (0xff23)
@@ -141,7 +146,7 @@ impl Noise {
141146
.update(self.nr44.trigger(), self.nr44.enable_length());
142147

143148
if self.nr44.trigger() {
144-
self.reload_timer();
149+
self.reload_initial_timer(self.nr43.step());
145150
self.lfsr.trigger(self.nr43.step());
146151
self.envelope
147152
.update(self.nr42.init(), self.nr42.count(), self.nr42.increase());
@@ -159,27 +164,37 @@ impl Noise {
159164
for _ in 0..times {
160165
self.update();
161166
}
167+
168+
self.write_amp();
162169
}
163170

164171
fn update(&mut self) {
165-
if !self.is_active() {
166-
return;
167-
}
168172
if !self.timer.tick() {
169173
return;
170174
}
171175

172176
self.reload_timer();
173177

174178
self.lfsr.update();
179+
}
175180

176-
self.dac.write(if self.lfsr.high() {
181+
fn write_amp(&mut self) {
182+
self.dac.write(if self.is_active() && self.lfsr.high() {
177183
self.envelope.amp()
178184
} else {
179185
0
180186
});
181187
}
182188

189+
fn reload_initial_timer(&mut self, short: bool) {
190+
self.timer.reset();
191+
192+
// TODO: Understand the initial delay more.
193+
self.timer.set_interval(
194+
self.timer_interval() + if short { 0 } else { 7 * self.timer_interval() } + 3,
195+
);
196+
}
197+
183198
fn reload_timer(&mut self) {
184199
self.timer.reset();
185200
self.timer.set_interval(self.timer_interval());
@@ -189,11 +204,19 @@ impl Noise {
189204
let divider = self.nr43.div_freq();
190205
let shift = self.nr43.shift_freq();
191206

192-
if divider == 0 {
193-
(5 << shift) / 10
194-
} else {
195-
divider << shift
196-
}
207+
// Divisor code Divisor
208+
// -----------------------
209+
// 0 8
210+
// 1 16
211+
// 2 32
212+
// 3 48
213+
// 4 64
214+
// 5 80
215+
// 6 96
216+
// 7 112
217+
let base = if divider == 0 { 8 } else { divider * 16 };
218+
219+
base << shift
197220
}
198221

199222
pub fn is_active(&self) -> bool {
@@ -204,6 +227,9 @@ impl Noise {
204227
self.power = true;
205228

206229
self.length_counter.power_on();
230+
231+
self.reload_timer();
232+
self.divider.reset();
207233
}
208234

209235
pub fn power_off(&mut self) {
@@ -216,8 +242,6 @@ impl Noise {
216242

217243
self.length_counter.power_off();
218244

219-
self.lfsr.reset();
220-
221245
self.dac.power_off();
222246
}
223247

@@ -239,35 +263,38 @@ struct Lfsr {
239263
impl Lfsr {
240264
fn new() -> Self {
241265
Self {
242-
value: 0,
266+
value: 0xff,
243267
short: false,
244268
}
245269
}
246270

247-
fn reset(&mut self) {
248-
self.value = 0;
249-
self.short = false;
250-
}
251-
252271
fn high(&self) -> bool {
253272
// Inverted bit 1
254273
self.value & 1 == 0
255274
}
256275

257276
fn trigger(&mut self, short: bool) {
258-
self.value = 0;
277+
self.short = short;
278+
self.value = 0xff;
279+
}
280+
281+
fn set_mode(&mut self, short: bool) {
259282
self.short = short;
260283
}
261284

262285
fn update(&mut self) {
263-
// NXOR bit 0 and 1.
264-
let bit = !((self.value & 0x01) ^ ((self.value & 0x02) >> 1)) & 1;
286+
// Xor bit 0 and 1.
287+
let bit = (self.value & 1) ^ ((self.value & 2) >> 1) & 1;
288+
289+
// Shift right.
290+
self.value >>= 1;
291+
292+
// Put the bit at bit 14 (i.e. 15 bits shift register)
293+
self.value = (self.value & !0x4000) | (bit << 14);
265294

266-
// Put XOR-ed result in bit 15 (and bit 7 in short mode)
267295
if self.short {
268-
self.value = ((self.value >> 1) & 0x7f7f) | (bit << 7) | (bit << 15);
269-
} else {
270-
self.value = ((self.value >> 1) & 0x7fff) | (bit << 15);
296+
// Put the bit at bit 6 (i.e. 7 bits shift register)
297+
self.value = (self.value & !0x0040) | (bit << 6);
271298
}
272299
}
273300
}

0 commit comments

Comments
 (0)