mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-11 09:31:34 +11:00
Do the zeroing of the buffer in assembly
This commit is contained in:
parent
33c948208a
commit
24749ac645
|
@ -150,13 +150,13 @@ agb_arm_func agb_rs__init_buffer
|
|||
push {r4-r5}
|
||||
|
||||
@ zero registers r3-r5
|
||||
mov r2, #constant_zero
|
||||
ldr r2, =constant_zero
|
||||
ldm r2, {r3-r5,r12}
|
||||
|
||||
1:
|
||||
@ zero 4 words worth of the buffer
|
||||
stmia r0, {r3-r5,r12}
|
||||
subs r1, r1, #16
|
||||
stmia r0!, {r3-r5,r12}
|
||||
subs r1, r1, #(4 * 4)
|
||||
@ loop if we haven't zeroed everything
|
||||
bne 1b
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use core::cell::RefCell;
|
||||
use core::mem;
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
use bare_metal::{CriticalSection, Mutex};
|
||||
|
||||
|
@ -27,6 +29,8 @@ extern "C" {
|
|||
fn agb_rs__mixer_add_stereo(sound_data: *const u8, sound_buffer: *mut Num<i16, 4>);
|
||||
|
||||
fn agb_rs__mixer_collapse(sound_buffer: *mut i8, input_buffer: *const Num<i16, 4>);
|
||||
|
||||
fn agb_rs__init_buffer(buffer: *mut MaybeUninit<Num<i16, 4>>, size_in_bytes: usize);
|
||||
}
|
||||
|
||||
pub struct Mixer {
|
||||
|
@ -231,8 +235,28 @@ impl MixerBuffer {
|
|||
}
|
||||
|
||||
fn write_channels<'a>(&mut self, channels: impl Iterator<Item = &'a mut SoundChannel>) {
|
||||
let mut buffer: [Num<i16, 4>; constants::SOUND_BUFFER_SIZE * 2] =
|
||||
[Num::new(0); constants::SOUND_BUFFER_SIZE * 2];
|
||||
// This code is equivalent to:
|
||||
// let mut buffer: [Num<i16, 4>; constants::SOUND_BUFFER_SIZE * 2] =
|
||||
// [Num::new(0); constants::SOUND_BUFFER_SIZE * 2];
|
||||
// but the above uses approximately 7% of the CPU time if running at 32kHz
|
||||
let mut buffer: [Num<i16, 4>; constants::SOUND_BUFFER_SIZE * 2] = {
|
||||
// Create an uninitialized array of `MaybeUninit`. The `assume_init` is
|
||||
// safe because the type we are claiming to have initialized here is a
|
||||
// bunch of `MaybeUninit`s, which do not require initialization.
|
||||
let mut data: [MaybeUninit<Num<i16, 4>>; constants::SOUND_BUFFER_SIZE * 2] =
|
||||
unsafe { MaybeUninit::uninit().assume_init() };
|
||||
|
||||
// Actually init the array (by filling it with zeros) and then transmute it (which is safe because
|
||||
// we have now zeroed everything)
|
||||
unsafe {
|
||||
agb_rs__init_buffer(
|
||||
data.as_mut_ptr(),
|
||||
mem::size_of::<Num<i16, 4>>() * data.len(),
|
||||
);
|
||||
|
||||
mem::transmute(data)
|
||||
}
|
||||
};
|
||||
|
||||
for channel in channels {
|
||||
if channel.is_done {
|
||||
|
|
Loading…
Reference in a new issue