mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-12 01:51:34 +11:00
Move timers to be fields in the controller
This commit is contained in:
parent
fd610d8cc1
commit
20511843ca
|
@ -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!(
|
||||||
|
|
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue