many apu improvements
This commit is contained in:
parent
0c0c42e8ba
commit
80d58ba497
|
@ -251,10 +251,10 @@ impl Apu {
|
||||||
} else {
|
} else {
|
||||||
0b01111111
|
0b01111111
|
||||||
};
|
};
|
||||||
v = set_or_clear_bit(v, 0, self.channels.one.enabled);
|
v = set_or_clear_bit(v, 0, self.channels.one.is_dac_enabled());
|
||||||
v = set_or_clear_bit(v, 1, self.channels.two.enabled);
|
v = set_or_clear_bit(v, 1, self.channels.two.is_dac_enabled());
|
||||||
v = set_or_clear_bit(v, 2, self.channels.three.enabled);
|
v = set_or_clear_bit(v, 2, self.channels.three.is_dac_enabled());
|
||||||
v = set_or_clear_bit(v, 3, self.channels.four.enabled);
|
v = set_or_clear_bit(v, 3, self.channels.four.is_dac_enabled());
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
// write-only registers
|
// write-only registers
|
||||||
|
@ -303,7 +303,17 @@ impl Apu {
|
||||||
self.mixer.ch3.left = Volume::from_bool(get_bit(data, 6));
|
self.mixer.ch3.left = Volume::from_bool(get_bit(data, 6));
|
||||||
self.mixer.ch4.left = Volume::from_bool(get_bit(data, 7));
|
self.mixer.ch4.left = Volume::from_bool(get_bit(data, 7));
|
||||||
}
|
}
|
||||||
0xFF26 => self.apu_enable = (1 << 7) == (data & 0b10000000),
|
0xFF26 => {
|
||||||
|
if !self.apu_enable {
|
||||||
|
for i in 0xFF10..0xFF20 {
|
||||||
|
self.mmio_write(i, 0x0);
|
||||||
|
}
|
||||||
|
for i in 0xFF21..0xFF25 {
|
||||||
|
self.mmio_write(i, 0x0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.apu_enable = (1 << 7) == (data & 0b10000000);
|
||||||
|
}
|
||||||
0xFF30..0xFF40 => self.channels.three.update_wave_ram(addr, data),
|
0xFF30..0xFF40 => self.channels.three.update_wave_ram(addr, data),
|
||||||
0xFF15 | 0xFF1F | 0xFF27..0xFF30 => {}
|
0xFF15 | 0xFF1F | 0xFF27..0xFF30 => {}
|
||||||
0x0..0xFF10 | 0xFF40..=0xFFFF => panic!("non-apu addr in apu"),
|
0x0..0xFF10 | 0xFF40..=0xFFFF => panic!("non-apu addr in apu"),
|
||||||
|
|
|
@ -146,8 +146,15 @@ impl PwmChannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trigger(&mut self) {
|
fn trigger(&mut self) {
|
||||||
|
if self.get_volume_and_envelope() & 0xF8 != 0 {
|
||||||
self.enabled = true;
|
self.enabled = true;
|
||||||
|
}
|
||||||
self.envelope = self.queued_envelope;
|
self.envelope = self.queued_envelope;
|
||||||
|
self.set_wave_timer();
|
||||||
|
self.wave_position = 0;
|
||||||
|
if self.length_timer >= 64 {
|
||||||
|
self.length_timer = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self, steps: usize) -> Vec<f32> {
|
pub fn tick(&mut self, steps: usize) -> Vec<f32> {
|
||||||
|
@ -199,7 +206,7 @@ impl PwmChannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn length_tick(&mut self) {
|
pub(super) fn length_tick(&mut self) {
|
||||||
if self.length_enable && self.enabled {
|
if self.length_enable {
|
||||||
self.length_timer += 1;
|
self.length_timer += 1;
|
||||||
if self.length_timer >= 64 {
|
if self.length_timer >= 64 {
|
||||||
self.enabled = false;
|
self.enabled = false;
|
||||||
|
@ -244,6 +251,9 @@ impl PwmChannel {
|
||||||
},
|
},
|
||||||
data & 0b111,
|
data & 0b111,
|
||||||
);
|
);
|
||||||
|
if data & 0b11111000 == 0 {
|
||||||
|
self.enabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_volume_and_envelope(&self) -> u8 {
|
pub(super) fn get_volume_and_envelope(&self) -> u8 {
|
||||||
|
@ -276,6 +286,10 @@ impl PwmChannel {
|
||||||
fn set_wave_timer(&mut self) {
|
fn set_wave_timer(&mut self) {
|
||||||
self.wave_timer = (2048 - self.wavelength) * 4;
|
self.wave_timer = (2048 - self.wavelength) * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn is_dac_enabled(&self) -> bool {
|
||||||
|
self.enabled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
@ -329,7 +343,7 @@ impl WaveChannel {
|
||||||
enabled,
|
enabled,
|
||||||
dac_enabled: false,
|
dac_enabled: false,
|
||||||
length_enable: false,
|
length_enable: false,
|
||||||
length_timer: 0xFF,
|
length_timer: 0,
|
||||||
volume: ShiftVolumePercent::Zero,
|
volume: ShiftVolumePercent::Zero,
|
||||||
wavelength,
|
wavelength,
|
||||||
wave_timer: (2048 - wavelength) * 2,
|
wave_timer: (2048 - wavelength) * 2,
|
||||||
|
@ -339,7 +353,14 @@ impl WaveChannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trigger(&mut self) {
|
fn trigger(&mut self) {
|
||||||
|
if self.dac_enabled {
|
||||||
self.enabled = true;
|
self.enabled = true;
|
||||||
|
};
|
||||||
|
self.set_wave_timer();
|
||||||
|
self.wave_position = 0;
|
||||||
|
if self.length_timer == 0xFF {
|
||||||
|
self.length_timer = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self, steps: usize) -> Vec<f32> {
|
pub fn tick(&mut self, steps: usize) -> Vec<f32> {
|
||||||
|
@ -369,9 +390,10 @@ impl WaveChannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn length_tick(&mut self) {
|
pub(super) fn length_tick(&mut self) {
|
||||||
if self.length_enable && self.enabled {
|
if self.length_enable {
|
||||||
self.length_timer = self.length_timer.saturating_add(1);
|
let (new, overflow) = self.length_timer.overflowing_add(1);
|
||||||
if self.length_timer == 0xFF {
|
self.length_timer = new;
|
||||||
|
if overflow {
|
||||||
self.enabled = false;
|
self.enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,6 +459,10 @@ impl WaveChannel {
|
||||||
fn set_wave_timer(&mut self) {
|
fn set_wave_timer(&mut self) {
|
||||||
self.wave_timer = (2048 - self.wavelength) * 2;
|
self.wave_timer = (2048 - self.wavelength) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn is_dac_enabled(&self) -> bool {
|
||||||
|
self.dac_enabled && self.enabled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
|
@ -524,9 +550,12 @@ impl NoiseChannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trigger(&mut self) {
|
fn trigger(&mut self) {
|
||||||
self.enabled = true;
|
// self.enabled = true;
|
||||||
self.envelope = self.queued_envelope;
|
self.envelope = self.queued_envelope;
|
||||||
self.lfsr.register = 0;
|
self.lfsr.register = 0;
|
||||||
|
if self.length_timer >= 64 {
|
||||||
|
self.length_timer = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self, steps: usize) -> Vec<f32> {
|
pub fn tick(&mut self, steps: usize) -> Vec<f32> {
|
||||||
|
@ -553,7 +582,7 @@ impl NoiseChannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn length_tick(&mut self) {
|
pub(super) fn length_tick(&mut self) {
|
||||||
if self.length_enable && self.enabled {
|
if self.length_enable {
|
||||||
self.length_timer += 1;
|
self.length_timer += 1;
|
||||||
if self.length_timer >= 64 {
|
if self.length_timer >= 64 {
|
||||||
self.enabled = false;
|
self.enabled = false;
|
||||||
|
@ -575,6 +604,9 @@ impl NoiseChannel {
|
||||||
},
|
},
|
||||||
data & 0b111,
|
data & 0b111,
|
||||||
);
|
);
|
||||||
|
if data & 0b11111000 == 0 {
|
||||||
|
self.enabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_volume_and_envelope(&self) -> u8 {
|
pub(super) fn get_volume_and_envelope(&self) -> u8 {
|
||||||
|
@ -615,4 +647,8 @@ impl NoiseChannel {
|
||||||
pub(super) fn get_control(&self) -> u8 {
|
pub(super) fn get_control(&self) -> u8 {
|
||||||
set_or_clear_bit(0xFF, 6, self.length_enable)
|
set_or_clear_bit(0xFF, 6, self.length_enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn is_dac_enabled(&self) -> bool {
|
||||||
|
self.get_volume_and_envelope() & 0xF8 == 0 && self.enabled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue