mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 00:31:34 +11:00
Add simple double buffer
This commit is contained in:
parent
334472f749
commit
72dbf2ef9c
|
@ -1,20 +1,24 @@
|
||||||
use crate::memory_mapped::MemoryMapped;
|
use crate::memory_mapped::MemoryMapped;
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct Mixer {}
|
pub struct Mixer {
|
||||||
|
buffer: MixerBuffer,
|
||||||
|
}
|
||||||
|
|
||||||
impl Mixer {
|
impl Mixer {
|
||||||
pub(crate) const unsafe fn new() -> Self {
|
pub(crate) const unsafe fn new() -> Self {
|
||||||
Mixer {}
|
Mixer {
|
||||||
|
buffer: MixerBuffer::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable(&self) {
|
pub fn enable(&self) {
|
||||||
set_sound_control_register_for_mixer();
|
set_sound_control_register_for_mixer();
|
||||||
|
set_timer_counter_for_frequency_and_enable(SOUND_FREQUENCY);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn play_sound_starting_at(&self, sound_memory: &[u8]) {
|
pub fn vblank(&mut self) {
|
||||||
set_timer_counter_for_frequency_and_enable(SOUND_FREQUENCY);
|
self.buffer.swap();
|
||||||
enable_dma1_for_sound(sound_memory);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +27,34 @@ impl Mixer {
|
||||||
const SOUND_FREQUENCY: i32 = 10512;
|
const SOUND_FREQUENCY: i32 = 10512;
|
||||||
const SOUND_BUFFER_SIZE: usize = 176;
|
const SOUND_BUFFER_SIZE: usize = 176;
|
||||||
|
|
||||||
|
struct MixerBuffer {
|
||||||
|
buffer1: [i8; SOUND_BUFFER_SIZE],
|
||||||
|
buffer2: [i8; SOUND_BUFFER_SIZE],
|
||||||
|
|
||||||
|
buffer_1_active: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MixerBuffer {
|
||||||
|
fn new() -> Self {
|
||||||
|
MixerBuffer {
|
||||||
|
buffer1: Default::default(),
|
||||||
|
buffer2: Default::default(),
|
||||||
|
|
||||||
|
buffer_1_active: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn swap(&mut self) {
|
||||||
|
if self.buffer_1_active {
|
||||||
|
enable_dma1_for_sound(&self.buffer1);
|
||||||
|
} else {
|
||||||
|
enable_dma1_for_sound(&self.buffer2);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.buffer_1_active = !self.buffer_1_active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Once we have proper DMA support, we should use that rather than hard coding these here too
|
// Once we have proper DMA support, we should use that rather than hard coding these here too
|
||||||
const DMA1_SOURCE_ADDR: MemoryMapped<u32> = unsafe { MemoryMapped::new(0x0400_00bc) };
|
const DMA1_SOURCE_ADDR: MemoryMapped<u32> = unsafe { MemoryMapped::new(0x0400_00bc) };
|
||||||
const DMA1_DEST_ADDR: MemoryMapped<u32> = unsafe { MemoryMapped::new(0x0400_00c0) };
|
const DMA1_DEST_ADDR: MemoryMapped<u32> = unsafe { MemoryMapped::new(0x0400_00c0) };
|
||||||
|
@ -38,14 +70,14 @@ const TIMER0_CONTROL: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0102
|
||||||
const SOUND_CONTROL: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0082) };
|
const SOUND_CONTROL: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0082) };
|
||||||
const SOUND_CONTROL_X: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0084) };
|
const SOUND_CONTROL_X: MemoryMapped<u16> = unsafe { MemoryMapped::new(0x0400_0084) };
|
||||||
|
|
||||||
fn enable_dma1_for_sound(sound_memory: &[u8]) {
|
fn enable_dma1_for_sound(sound_memory: &[i8]) {
|
||||||
let dest_fixed: u16 = 2 << 5; // dest addr control = fixed
|
let dest_fixed: u16 = 2 << 5; // dest addr control = fixed
|
||||||
let repeat: u16 = 1 << 9;
|
let repeat: u16 = 1 << 9;
|
||||||
let transfer_type: u16 = 1 << 10; // transfer in words
|
let transfer_type: u16 = 1 << 10; // transfer in words
|
||||||
let dma_start_timing: u16 = 3 << 12; // sound fifo timing
|
let dma_start_timing: u16 = 3 << 12; // sound fifo timing
|
||||||
let enable: u16 = 1 << 15; // enable
|
let enable: u16 = 1 << 15; // enable
|
||||||
|
|
||||||
let address: *const u8 = &sound_memory[0];
|
let address: *const i8 = &sound_memory[0];
|
||||||
DMA1_SOURCE_ADDR.set(address as u32);
|
DMA1_SOURCE_ADDR.set(address as u32);
|
||||||
DMA1_DEST_ADDR.set(FIFOA_DEST_ADDR);
|
DMA1_DEST_ADDR.set(FIFOA_DEST_ADDR);
|
||||||
DMA1_CONTROL.set(dest_fixed | repeat | transfer_type | dma_start_timing | enable);
|
DMA1_CONTROL.set(dest_fixed | repeat | transfer_type | dma_start_timing | enable);
|
||||||
|
|
Loading…
Reference in a new issue