Fix timer bugs

Former-commit-id: 9839368895dca306b66a095ab0b9386c77bd2c12
This commit is contained in:
Michel Heily 2019-08-07 09:44:47 +03:00
parent c72bbb96fd
commit fe071bf1ec
2 changed files with 24 additions and 16 deletions

View file

@ -237,19 +237,19 @@ impl Bus for IoRegs {
REG_TM1CNT_L => {
io.timers[1].timer_data = value;
io.timers[0].initial_data = value;
io.timers[1].initial_data = value;
}
REG_TM1CNT_H => io.timers[1].timer_ctl.0 = value,
REG_TM2CNT_L => {
io.timers[2].timer_data = value;
io.timers[0].initial_data = value;
io.timers[2].initial_data = value;
}
REG_TM2CNT_H => io.timers[2].timer_ctl.0 = value,
REG_TM3CNT_L => {
io.timers[3].timer_data = value;
io.timers[0].initial_data = value;
io.timers[3].initial_data = value;
}
REG_TM3CNT_H => io.timers[3].timer_ctl.0 = value,

View file

@ -20,7 +20,7 @@ pub struct Timer {
}
pub enum TimerAction {
Overflow,
Overflow(usize),
Increment,
}
@ -50,6 +50,7 @@ impl Timer {
}
pub fn add_cycles(&mut self, cycles: usize, irqs: &mut IrqBitmask) -> TimerAction {
let mut num_overflows = 0;
self.cycles += cycles;
let frequency = self.frequency();
@ -60,14 +61,17 @@ impl Timer {
if self.timer_ctl.irq_enabled() {
irqs.add_irq(self.get_irq());
}
println!("timer{} overflow", self.timer_id);
return TimerAction::Overflow;
self.timer_data = self.initial_data;
num_overflows += 1;
}
}
if num_overflows > 0 {
return TimerAction::Overflow(num_overflows);
} else {
return TimerAction::Increment;
}
}
}
#[derive(Debug)]
pub struct Timers([Timer; 4]);
@ -96,16 +100,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 => match i {
TimerAction::Overflow(num_overflows) => {
println!("timer{} overflowed {} times", i, num_overflows);
match i {
3 => {}
_ => {
let next_i = i + 1;
if self[next_i].timer_ctl.cascade() {
println!("{:?} is cascade!", self[next_i]);
self[next_i].add_cycles(1, irqs);
println!("cascading into timer{}", next_i);
self[next_i].add_cycles(num_overflows, irqs);
}
}
},
}
}
TimerAction::Increment => {}
_ => {}
}
}