From bb08b2f48e97bbb70bcfb50d4020e1b60c3caaa8 Mon Sep 17 00:00:00 2001 From: Michel Heily Date: Wed, 20 Nov 2019 05:20:46 +0200 Subject: [PATCH] Improve timers Former-commit-id: 02985b13aec6ac4ce52952b9bc505e48ebbb94e6 --- src/core/iodev.rs | 8 +++---- src/core/timer.rs | 46 +++++++++++++++++++++++++++++++---------- src/debugger/command.rs | 2 +- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/core/iodev.rs b/src/core/iodev.rs index b3ed5e4..35c55ae 100644 --- a/src/core/iodev.rs +++ b/src/core/iodev.rs @@ -208,25 +208,25 @@ impl Bus for IoDevices { io.timers[0].timer_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 => { io.timers[1].timer_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 => { io.timers[2].timer_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 => { io.timers[3].timer_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 => { let ofs = io_addr - DMA_BASE; diff --git a/src/core/timer.rs b/src/core/timer.rs index 0a8cd42..0fe4989 100644 --- a/src/core/timer.rs +++ b/src/core/timer.rs @@ -74,24 +74,43 @@ impl Timer { } #[derive(Debug)] -pub struct Timers([Timer; 4]); +pub struct Timers { + timers: [Timer; 4], + pub trace: bool, +} impl std::ops::Index for Timers { type Output = Timer; fn index(&self, index: usize) -> &Self::Output { - &self.0[index] + &self.timers[index] } } impl std::ops::IndexMut for Timers { fn index_mut(&mut self, index: usize) -> &mut Self::Output { - &mut self.0[index] + &mut self.timers[index] } } impl 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 { if self[i].timer_ctl.enabled() && !self[i].timer_ctl.cascade() { match self[i].add_cycles(cycles, irqs) { - TimerAction::Overflow(num_overflows) => match i { - 3 => {} - _ => { - let next_i = i + 1; - if self[next_i].timer_ctl.cascade() { - self[next_i].add_cycles(num_overflows, irqs); + TimerAction::Overflow(num_overflows) => { + if self.trace { + println!("TMR{} overflown!", i); + } + match i { + 3 => {} + _ => { + let next_i = i + 1; + if self[next_i].timer_ctl.cascade() { + self[next_i].add_cycles(num_overflows, irqs); + } } } - }, + } TimerAction::Increment => {} } } diff --git a/src/debugger/command.rs b/src/debugger/command.rs index b4f83d8..0146563 100644 --- a/src/debugger/command.rs +++ b/src/debugger/command.rs @@ -203,7 +203,7 @@ impl Debugger { println!("[*] dma tracing not implemented"); } if flags.contains(TraceFlags::TRACE_TIMERS) { - println!("[*] timers tracing not implemented"); + self.gba.sysbus.io.timers.trace = !self.gba.sysbus.io.timers.trace; } } }