apu
This commit is contained in:
parent
8a8d45cbff
commit
20ded5f56c
|
@ -21,6 +21,8 @@ use dmc::DMC;
|
||||||
// need all samples, it needs one from the stream 44100 time per second. So just an if statement, if time has passed grab a sample.
|
// need all samples, it needs one from the stream 44100 time per second. So just an if statement, if time has passed grab a sample.
|
||||||
// But then that won't be running during PPU 60Hz sleep... So run audio in its own thread... Except then it won't work on Windows because of SDL...
|
// But then that won't be running during PPU 60Hz sleep... So run audio in its own thread... Except then it won't work on Windows because of SDL...
|
||||||
// So just run the console in its own thread and video/audio in the main thread... But that's annoying.
|
// So just run the console in its own thread and video/audio in the main thread... But that's annoying.
|
||||||
|
// No. Don't have to be concerned about the audio device, that's solved by the buffer, and the 44100 samples get fed in batches of 4096 from the large buffer,
|
||||||
|
// when the device needs them, which is accomplished just by calling .resume() before the main loop starts. So a large buffer really should allow for the 60Hz sleep lock.
|
||||||
|
|
||||||
pub struct Apu {
|
pub struct Apu {
|
||||||
square1: Square,
|
square1: Square,
|
||||||
|
@ -84,6 +86,7 @@ impl Apu {
|
||||||
0x4006 => self.square2.timer_low(value),
|
0x4006 => self.square2.timer_low(value),
|
||||||
0x4007 => self.square2.timer_high(value),
|
0x4007 => self.square2.timer_high(value),
|
||||||
0x4008 => self.triangle.counter(value),
|
0x4008 => self.triangle.counter(value),
|
||||||
|
0x4009 => (),
|
||||||
0x400A => self.triangle.timer_low(value),
|
0x400A => self.triangle.timer_low(value),
|
||||||
0x400B => self.triangle.timer_high(value),
|
0x400B => self.triangle.timer_high(value),
|
||||||
0x400C => self.noise.envelope(value),
|
0x400C => self.noise.envelope(value),
|
||||||
|
@ -204,7 +207,6 @@ impl Apu {
|
||||||
if self.dmc.interrupt {
|
if self.dmc.interrupt {
|
||||||
val |= 1<<7;
|
val |= 1<<7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Reading this register clears the frame interrupt flag (but not the DMC interrupt flag).
|
// Reading this register clears the frame interrupt flag (but not the DMC interrupt flag).
|
||||||
self.frame_interrupt = false;
|
self.frame_interrupt = false;
|
||||||
|
|
|
@ -16,6 +16,9 @@ pub struct Square {
|
||||||
envelope: usize,
|
envelope: usize,
|
||||||
sweep: usize,
|
sweep: usize,
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
|
decay_counter: u8,
|
||||||
|
start: bool,
|
||||||
|
divider: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Square {
|
impl Square {
|
||||||
|
@ -31,6 +34,9 @@ impl Square {
|
||||||
sweep: 0,
|
sweep: 0,
|
||||||
sample: 0,
|
sample: 0,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
decay_counter: 0,
|
||||||
|
start: false,
|
||||||
|
divider: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,21 +44,42 @@ impl Square {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clock_frame_counter(&mut self) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clock_envelope(&mut self) {
|
||||||
|
if self.start {
|
||||||
|
self.envelope -= 1;
|
||||||
|
self.start = false;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// $4000/$4004
|
||||||
pub fn duty(&mut self, value: u8) {
|
pub fn duty(&mut self, value: u8) {
|
||||||
self.duty_cycle = duty_cycle_sequences[(value >> 6) as usize];
|
self.duty_cycle = duty_cycle_sequences[(value >> 6) as usize];
|
||||||
self.length_counter_halt = value & (1<<5) != 0;
|
self.length_counter_halt = value & (1<<5) != 0;
|
||||||
self.constant_volume_flag = value & (1<<4) != 0;
|
self.constant_volume_flag = value & (1<<4) != 0;
|
||||||
|
if self.constant_volume_flag {
|
||||||
|
self.envelope = value & 0b1111;
|
||||||
|
} else {
|
||||||
|
self.envelope = self.decay_counter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $4001/$4005
|
||||||
pub fn sweep(&mut self, value: u8) {
|
pub fn sweep(&mut self, value: u8) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $4002/$4006
|
||||||
pub fn timer_low(&mut self, value: u8) {
|
pub fn timer_low(&mut self, value: u8) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $4003/$4007
|
||||||
pub fn timer_high(&mut self, value: u8) {
|
pub fn timer_high(&mut self, value: u8) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue