Improve timers
Former-commit-id: 02985b13aec6ac4ce52952b9bc505e48ebbb94e6
This commit is contained in:
parent
3c3129c73c
commit
bb08b2f48e
|
@ -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;
|
||||||
|
|
|
@ -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 => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue