Move timers to be fields in the controller

This commit is contained in:
Gwilym Kuiper 2021-11-18 22:14:39 +00:00
parent fd610d8cc1
commit 20511843ca
2 changed files with 45 additions and 61 deletions

View file

@ -4,7 +4,7 @@
extern crate agb; extern crate agb;
use agb::sound::mixer::SoundChannel; use agb::sound::mixer::SoundChannel;
use agb::{include_wav, timer::Timer, Gba}; use agb::{include_wav, Gba};
// Music - "Let it in" by Josh Woodward, free download at http://joshwoodward.com // Music - "Let it in" by Josh Woodward, free download at http://joshwoodward.com
const LET_IT_IN: &[u8] = include_wav!("examples/JoshWoodward-LetItIn.wav"); const LET_IT_IN: &[u8] = include_wav!("examples/JoshWoodward-LetItIn.wav");
@ -14,11 +14,9 @@ fn main() -> ! {
let mut gba = Gba::new(); let mut gba = Gba::new();
let vblank_provider = agb::interrupt::VBlank::get(); let vblank_provider = agb::interrupt::VBlank::get();
let mut timer_controller = gba.timer; let timer_controller = gba.timer;
timer_controller.set_overflow_amount(Timer::Timer1, u16::MAX); let mut timer = timer_controller.timer1;
timer_controller.set_enabled(Timer::Timer1, true); timer.set_enabled(true);
timer_controller.set_overflow_amount(Timer::Timer2, u16::MAX);
timer_controller.set_cascade(Timer::Timer2, true);
let mut mixer = gba.mixer.mixer(); let mut mixer = gba.mixer.mixer();
mixer.enable(); mixer.enable();
@ -30,21 +28,14 @@ fn main() -> ! {
let mut frame_counter = 0i32; let mut frame_counter = 0i32;
loop { loop {
vblank_provider.wait_for_vblank(); vblank_provider.wait_for_vblank();
let before_mixing_cycles_lo = timer_controller.get_value(Timer::Timer1); let before_mixing_cycles = timer.get_value();
let before_mixing_cycles_hi = timer_controller.get_value(Timer::Timer2);
mixer.vblank(); mixer.vblank();
let after_mixing_cycles_lo = timer_controller.get_value(Timer::Timer1); let after_mixing_cycles = timer.get_value();
let after_mixing_cycles_hi = timer_controller.get_value(Timer::Timer2);
frame_counter = frame_counter.wrapping_add(1); frame_counter = frame_counter.wrapping_add(1);
if frame_counter % 128 == 0 { if frame_counter % 128 == 0 {
let before_mixing_cycles = let total_cycles = after_mixing_cycles.wrapping_sub(before_mixing_cycles) as u32;
((before_mixing_cycles_hi as u32) << 16) | before_mixing_cycles_lo as u32;
let after_mixing_cycles =
((after_mixing_cycles_hi as u32) << 16) | after_mixing_cycles_lo as u32;
let total_cycles = after_mixing_cycles.wrapping_sub(before_mixing_cycles);
let percent = (total_cycles * 100) / 280896; let percent = (total_cycles * 100) / 280896;
agb::println!( agb::println!(

View file

@ -8,14 +8,6 @@ const fn timer_control(timer: usize) -> MemoryMapped<u16> {
unsafe { MemoryMapped::new(0x0400_0102 + 4 * timer) } unsafe { MemoryMapped::new(0x0400_0102 + 4 * timer) }
} }
#[derive(Clone, Copy)]
pub enum Timer {
Timer0,
Timer1,
Timer2,
Timer3,
}
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum Divider { pub enum Divider {
// 16.78MHz or 59.59ns // 16.78MHz or 59.59ns
@ -42,48 +34,56 @@ impl Divider {
} }
#[non_exhaustive] #[non_exhaustive]
pub struct TimerController {} pub struct Timer<const N: usize> {}
#[non_exhaustive]
pub struct TimerController {
pub timer0: Timer<0>,
pub timer1: Timer<1>,
pub timer2: Timer<2>,
pub timer3: Timer<3>,
}
impl TimerController { impl TimerController {
pub(crate) const unsafe fn new() -> Self { pub(crate) const unsafe fn new() -> Self {
Self {} Self {
} timer0: Timer::new(),
timer1: Timer::new(),
pub fn set_overflow_amount(&mut self, timer: Timer, n: u16) { timer2: Timer::new(),
timer.set_overflow_amount(n); timer3: Timer::new(),
} }
pub fn get_value(&mut self, timer: Timer) -> u16 {
timer.get_value()
}
pub fn set_divider(&mut self, timer: Timer, divider: Divider) {
timer
.control_register()
.set_bits(divider.get_as_bits(), 2, 0);
}
pub fn set_enabled(&mut self, timer: Timer, enabled: bool) {
let bit = if enabled { 1 } else { 0 };
timer.control_register().set_bits(bit, 1, 7);
}
pub fn set_cascade(&mut self, timer: Timer, cascade: bool) {
let bit = if cascade { 1 } else { 0 };
timer.control_register().set_bits(bit, 1, 2);
} }
} }
impl Timer { impl<const N: usize> Timer<N> {
fn set_overflow_amount(&self, n: u16) { const unsafe fn new() -> Self {
Self {}
}
pub fn set_overflow_amount(&self, n: u16) {
let count_up_value = 0u16.wrapping_sub(n); let count_up_value = 0u16.wrapping_sub(n);
self.data_register().set(count_up_value); self.data_register().set(count_up_value);
} }
fn get_value(&self) -> u16 { pub fn get_value(&self) -> u16 {
self.data_register().get() self.data_register().get()
} }
pub fn set_divider(&mut self, divider: Divider) {
self.control_register()
.set_bits(divider.get_as_bits(), 2, 0);
}
pub fn set_enabled(&mut self, enabled: bool) {
let bit = if enabled { 1 } else { 0 };
self.control_register().set_bits(bit, 1, 7);
}
pub fn set_cascade(&mut self, cascade: bool) {
let bit = if cascade { 1 } else { 0 };
self.control_register().set_bits(bit, 1, 2);
}
fn data_register(&self) -> MemoryMapped<u16> { fn data_register(&self) -> MemoryMapped<u16> {
timer_data(self.get_timer_number()) timer_data(self.get_timer_number())
} }
@ -93,13 +93,6 @@ impl Timer {
} }
fn get_timer_number(&self) -> usize { fn get_timer_number(&self) -> usize {
use Timer::*; N
match self {
Timer0 => 0,
Timer1 => 1,
Timer2 => 2,
Timer3 => 3,
}
} }
} }