Add channel 2 support

This commit is contained in:
Gwilym Kuiper 2021-04-16 00:21:13 +01:00 committed by Corwin
parent 0e27b956de
commit 781fc291f0
2 changed files with 53 additions and 14 deletions

View file

@ -20,5 +20,12 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
sound::DutyCycle::Half, sound::DutyCycle::Half,
); );
gba.sound.channel2().play_sound(
1524,
Some(0),
&sound::EnvelopeSettings::default(),
sound::DutyCycle::Half,
);
loop {} loop {}
} }

View file

@ -4,6 +4,9 @@ const CHANNEL_1_SWEEP: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_006
const CHANNEL_1_LENGTH_DUTY_ENVELOPE: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0062) }; const CHANNEL_1_LENGTH_DUTY_ENVELOPE: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0062) };
const CHANNEL_1_FREQUENCY_CONTROL: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0064) }; const CHANNEL_1_FREQUENCY_CONTROL: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0064) };
const CHANNEL_2_LENGTH_DUTY_ENVELOPE: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0068) };
const CHANNEL_2_FREQUENCY_CONTROL: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_006c) };
const MASTER_SOUND_VOLUME_ENABLE: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0080) }; const MASTER_SOUND_VOLUME_ENABLE: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0080) };
const MASTER_SOUND_VOLUME_MIXING: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0082) }; const MASTER_SOUND_VOLUME_MIXING: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0082) };
const MASTER_SOUND_STATUS: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0084) }; const MASTER_SOUND_STATUS: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0084) };
@ -20,6 +23,10 @@ impl Sound {
Channel1 {} Channel1 {}
} }
pub fn channel2(&self) -> Channel2 {
Channel2 {}
}
pub fn enable(&self) { pub fn enable(&self) {
MASTER_SOUND_STATUS.set_bits(1, 1, 7); MASTER_SOUND_STATUS.set_bits(1, 1, 7);
@ -31,20 +38,6 @@ impl Sound {
#[non_exhaustive] #[non_exhaustive]
pub struct Channel1 {} pub struct Channel1 {}
pub enum SoundDirection {
Increase,
Decrease,
}
impl SoundDirection {
fn as_bits(&self) -> u16 {
match &self {
SoundDirection::Increase => 1,
SoundDirection::Decrease => 0,
}
}
}
impl Channel1 { impl Channel1 {
pub fn play_sound( pub fn play_sound(
&self, &self,
@ -69,6 +62,45 @@ impl Channel1 {
} }
} }
#[non_exhaustive]
pub struct Channel2 {}
impl Channel2 {
pub fn play_sound(
&self,
frequency: u16,
length: Option<u8>,
envelope_settings: &EnvelopeSettings,
duty_cycle: DutyCycle,
) {
let length_bits = length.unwrap_or(0) as u16;
assert!(length_bits < 64, "Length must be less than 64");
let length_flag: u16 = length.map(|_| 1 << 14).unwrap_or(0);
let initial: u16 = 1 << 15;
assert!(frequency < 2048, "Frequency must be less than 2048");
CHANNEL_2_LENGTH_DUTY_ENVELOPE
.set(envelope_settings.as_bits() | duty_cycle.as_bits() | length_bits);
CHANNEL_2_FREQUENCY_CONTROL.set(frequency | length_flag | initial);
}
}
pub enum SoundDirection {
Increase,
Decrease,
}
impl SoundDirection {
fn as_bits(&self) -> u16 {
match &self {
SoundDirection::Increase => 1,
SoundDirection::Decrease => 0,
}
}
}
pub struct SweepSettings { pub struct SweepSettings {
number_of_sweep_shifts: u8, number_of_sweep_shifts: u8,
sound_direction: SoundDirection, sound_direction: SoundDirection,