feat(snd): implement ch4

This commit is contained in:
Rekai Nyangadzayi Musuka 2021-06-15 01:11:18 -05:00
parent 5b041d4713
commit fe8598fd61
2 changed files with 125 additions and 1 deletions

View File

@ -231,6 +231,10 @@ impl BusIo for Bus {
0x1B => self.snd.ch3.len,
0x1C => self.snd.ch3.volume(),
0x1E => self.snd.ch3.freq_hi.into(),
0x20 => self.snd.ch4.len(),
0x21 => self.snd.ch4.envelope.into(),
0x22 => self.snd.ch4.poly.into(),
0x23 => self.snd.ch4.freq_data.into(),
0x24 => self.snd.ctrl.channel.into(),
0x25 => self.snd.ctrl.output.into(),
0x26 => self.snd.ctrl.status.into(),
@ -344,6 +348,10 @@ impl BusIo for Bus {
0x1C => self.snd.ch3.set_volume(byte),
0x1D => self.snd.ch3.freq_lo = byte,
0x1E => self.snd.ch3.freq_hi = byte.into(),
0x20 => self.snd.ch4.set_len(byte),
0x21 => self.snd.ch4.envelope = byte.into(),
0x22 => self.snd.ch4.poly = byte.into(),
0x23 => self.snd.ch4.freq_data = byte.into(),
0x24 => self.snd.ctrl.channel = byte.into(),
0x25 => self.snd.ctrl.output = byte.into(),
0x26 => self.snd.ctrl.status = byte.into(), // FIXME: Should we control which bytes are written to here?

View File

@ -11,7 +11,8 @@ pub(crate) struct Sound {
pub(crate) ch2: Channel2,
/// Wave
pub(crate) ch3: Channel3,
// pub(crate) ch4: Channel4,
/// Noise
pub(crate) ch4: Channel4,
}
impl Sound {
@ -81,6 +82,12 @@ impl From<u8> for FrequencyType {
}
}
impl From<FrequencyType> for u8 {
fn from(freq_type: FrequencyType) -> Self {
freq_type as u8
}
}
impl Default for FrequencyType {
fn default() -> Self {
Self::Counter
@ -377,6 +384,115 @@ impl Default for Channel3Volume {
}
}
#[derive(Debug, Clone, Copy, Default)]
pub(crate) struct Channel4 {
/// 0xFF20 | NR41 - Channel 4 Sound Length
len: u8,
/// 0xFF21 | NR42 - Channel 4 Volume Envelope
pub(crate) envelope: VolumeEnvelope,
/// 0xFF22 | NR43 - Chanel 4 Polynomial Counter
pub(crate) poly: PolynomialCounter,
/// 0xFF23 | NR44 - Channel 4 Counter / Consecutive Selector and Restart
pub(crate) freq_data: Channel4Frequency,
}
impl Channel4 {
pub(crate) fn len(&self) -> u8 {
self.len & 0x3F
}
pub(crate) fn set_len(&mut self, byte: u8) {
self.len = byte & 0x3F;
}
}
bitfield! {
pub struct PolynomialCounter(u8);
impl Debug;
freq, set_freq: 7, 4;
from into CounterWidth, counter_width, set_counter_width: 3, 3;
div_ratio, set_div_ratio: 2, 0;
}
impl Copy for PolynomialCounter {}
impl Clone for PolynomialCounter {
fn clone(&self) -> Self {
*self
}
}
impl Default for PolynomialCounter {
fn default() -> Self {
Self(0)
}
}
impl From<u8> for PolynomialCounter {
fn from(byte: u8) -> Self {
Self(byte)
}
}
impl From<PolynomialCounter> for u8 {
fn from(poly: PolynomialCounter) -> Self {
poly.0
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) enum CounterWidth {
Long, // 15 bits long
Short, // 7 bits long
}
impl From<u8> for CounterWidth {
fn from(byte: u8) -> Self {
match byte & 0x01 {
0b00 => Self::Short,
0b01 => Self::Long,
_ => unreachable!("{:#04X} is not a valid value for CounterWidth"),
}
}
}
impl From<CounterWidth> for u8 {
fn from(counter_width: CounterWidth) -> Self {
counter_width as u8
}
}
bitfield! {
pub struct Channel4Frequency(u8);
impl Debug;
_, set_initial: 7;
from into FrequencyType, freq_type, set_freq_type: 6, 6;
}
impl Copy for Channel4Frequency {}
impl Clone for Channel4Frequency {
fn clone(&self) -> Self {
*self
}
}
impl Default for Channel4Frequency {
fn default() -> Self {
Self(0)
}
}
impl From<u8> for Channel4Frequency {
fn from(byte: u8) -> Self {
Self(byte & 0xC0) // Only bits 7 and 6 hold anything of value
}
}
impl From<Channel4Frequency> for u8 {
fn from(state: Channel4Frequency) -> Self {
state.0 & 0x40 // Only bit 6 holds anything of value
}
}
bitfield! {
pub struct SoundOutput(u8);
impl Debug;