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].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;

View file

@ -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<usize> for Timers {
type Output = Timer;
fn index(&self, index: usize) -> &Self::Output {
&self.0[index]
&self.timers[index]
}
}
impl std::ops::IndexMut<usize> 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 => {}
}
}

View file

@ -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;
}
}
}