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