Improve timers

Former-commit-id: 02985b13aec6ac4ce52952b9bc505e48ebbb94e6
This commit is contained in:
Michel Heily 2019-11-20 05:20:46 +02:00
parent 3c3129c73c
commit bb08b2f48e
3 changed files with 40 additions and 16 deletions

View file

@ -208,25 +208,25 @@ impl Bus for IoDevices {
io.timers[0].timer_data = value; io.timers[0].timer_data = value;
io.timers[0].initial_data = value; io.timers[0].initial_data = value;
} }
REG_TM0CNT_H => io.timers[0].timer_ctl.0 = value, REG_TM0CNT_H => io.timers.write_timer_ctl(0, value),
REG_TM1CNT_L => { REG_TM1CNT_L => {
io.timers[1].timer_data = value; io.timers[1].timer_data = value;
io.timers[1].initial_data = value; io.timers[1].initial_data = value;
} }
REG_TM1CNT_H => io.timers[1].timer_ctl.0 = value, REG_TM1CNT_H => io.timers.write_timer_ctl(1, value),
REG_TM2CNT_L => { REG_TM2CNT_L => {
io.timers[2].timer_data = value; io.timers[2].timer_data = value;
io.timers[2].initial_data = value; io.timers[2].initial_data = value;
} }
REG_TM2CNT_H => io.timers[2].timer_ctl.0 = value, REG_TM2CNT_H => io.timers.write_timer_ctl(2, value),
REG_TM3CNT_L => { REG_TM3CNT_L => {
io.timers[3].timer_data = value; io.timers[3].timer_data = value;
io.timers[3].initial_data = value; io.timers[3].initial_data = value;
} }
REG_TM3CNT_H => io.timers[3].timer_ctl.0 = value, REG_TM3CNT_H => io.timers.write_timer_ctl(3, value),
DMA_BASE..=REG_DMA3CNT_H => { DMA_BASE..=REG_DMA3CNT_H => {
let ofs = io_addr - DMA_BASE; let ofs = io_addr - DMA_BASE;

View file

@ -74,24 +74,43 @@ impl Timer {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct Timers([Timer; 4]); pub struct Timers {
timers: [Timer; 4],
pub trace: bool,
}
impl std::ops::Index<usize> for Timers { impl std::ops::Index<usize> for Timers {
type Output = Timer; type Output = Timer;
fn index(&self, index: usize) -> &Self::Output { fn index(&self, index: usize) -> &Self::Output {
&self.0[index] &self.timers[index]
} }
} }
impl std::ops::IndexMut<usize> for Timers { impl std::ops::IndexMut<usize> for Timers {
fn index_mut(&mut self, index: usize) -> &mut Self::Output { fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.0[index] &mut self.timers[index]
} }
} }
impl Timers { impl Timers {
pub fn new() -> Timers { pub fn new() -> Timers {
Timers([Timer::new(0), Timer::new(1), Timer::new(2), Timer::new(3)]) Timers {
timers: [Timer::new(0), Timer::new(1), Timer::new(2), Timer::new(3)],
trace: false,
}
}
pub fn write_timer_ctl(&mut self, id: usize, value: u16) {
let old_enabled = self[id].timer_ctl.enabled();
self[id].timer_ctl.0 = value;
let new_enabled = self[id].timer_ctl.enabled();
if self.trace && old_enabled != new_enabled {
println!(
"TMR{} {}",
id,
if new_enabled { "enabled" } else { "disabled" }
);
}
} }
} }
@ -100,15 +119,20 @@ impl SyncedIoDevice for Timers {
for i in 0..4 { for i in 0..4 {
if self[i].timer_ctl.enabled() && !self[i].timer_ctl.cascade() { if self[i].timer_ctl.enabled() && !self[i].timer_ctl.cascade() {
match self[i].add_cycles(cycles, irqs) { match self[i].add_cycles(cycles, irqs) {
TimerAction::Overflow(num_overflows) => match i { TimerAction::Overflow(num_overflows) => {
3 => {} if self.trace {
_ => { println!("TMR{} overflown!", i);
let next_i = i + 1; }
if self[next_i].timer_ctl.cascade() { match i {
self[next_i].add_cycles(num_overflows, irqs); 3 => {}
_ => {
let next_i = i + 1;
if self[next_i].timer_ctl.cascade() {
self[next_i].add_cycles(num_overflows, irqs);
}
} }
} }
}, }
TimerAction::Increment => {} TimerAction::Increment => {}
} }
} }

View file

@ -203,7 +203,7 @@ impl Debugger {
println!("[*] dma tracing not implemented"); println!("[*] dma tracing not implemented");
} }
if flags.contains(TraceFlags::TRACE_TIMERS) { if flags.contains(TraceFlags::TRACE_TIMERS) {
println!("[*] timers tracing not implemented"); self.gba.sysbus.io.timers.trace = !self.gba.sysbus.io.timers.trace;
} }
} }
} }