Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timers: Support 16 bit timer writes and reset even when interrupts are disabled #478

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/core/ee/timers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,7 @@ void EmotionTiming::write32(uint32_t addr, uint32_t value)
scheduler->set_timer_pause(events[id], !is_timer_enabled(id));
scheduler->set_timer_clockrate(events[id], Scheduler::BUS_CLOCKRATE / timers[id].clock_scale);
scheduler->set_timer_int_mask(events[id],
timers[id].control.overflow_int_enable,
timers[id].control.compare_int_enable);
timers[id].control.overflow_int_enable);
break;
case 2:
printf("[EE Timing] Write32 timer %d compare: $%08X\n", id, value);
Expand Down
5 changes: 5 additions & 0 deletions src/core/emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,11 @@ void Emulator::write16(uint32_t address, uint16_t value)
dmac.write16(address, value);
return;
}
if (address >= 0x10000000 && address < 0x10002000)
{
timers.write32(address, value);
return;
}
if (address >= 0x1C000000 && address < 0x1C200000)
{
*(uint16_t*)&IOP_RAM[address & 0x1FFFFF] = value;
Expand Down
14 changes: 8 additions & 6 deletions src/core/iop/iop_timers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,13 @@ void IOPTiming::IRQ_test(int index, bool overflow)
timers[index].control.compare_interrupt = true;
}

if (!timers[index].control.repeat_int)
timers[index].control.int_enable = false;
else if (timers[index].control.toggle_int)
timers[index].control.int_enable ^= true;
if (timers[index].control.compare_interrupt_enabled)
{
if (!timers[index].control.repeat_int)
timers[index].control.int_enable = false;
else if (timers[index].control.toggle_int)
timers[index].control.int_enable ^= true;
}
}

uint32_t IOPTiming::read_counter(int index)
Expand Down Expand Up @@ -194,8 +197,7 @@ void IOPTiming::write_control(int index, uint16_t value)
scheduler->set_timer_counter(events[index], 0);
scheduler->set_timer_pause(events[index], !timers[index].control.started);
scheduler->set_timer_int_mask(events[index],
timers[index].control.overflow_interrupt_enabled,
timers[index].control.compare_interrupt_enabled);
timers[index].control.overflow_interrupt_enabled);
}

void IOPTiming::write_target(int index, uint32_t value)
Expand Down
7 changes: 2 additions & 5 deletions src/core/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,7 @@ void Scheduler::timer_event(uint64_t index)
if ((old_counter <= timers[index].target && timers[index].counter >= timers[index].target) ||
(old_counter >= timers[index].target && timers[index].counter >= (timers[index].target | (timers[index].overflow_mask + 1))))
{
if (timers[index].can_target)
timer_callbacks[cb_id](timers[index].param, false);
timer_callbacks[cb_id](timers[index].param, false);
}

//Overflow check
Expand Down Expand Up @@ -229,7 +228,6 @@ uint64_t Scheduler::create_timer(int callback_id, uint64_t overflow_mask, uint64
timer.param = param;
timer.callback_id = callback_id;
timer.can_overflow = false;
timer.can_target = false;

timers.push_back(timer);
return timers.size() - 1;
Expand Down Expand Up @@ -270,10 +268,9 @@ void Scheduler::set_timer_pause(uint64_t timer_id, bool paused)
timers[timer_id].paused = paused;
}

void Scheduler::set_timer_int_mask(uint64_t timer_id, bool can_overflow, bool can_target)
void Scheduler::set_timer_int_mask(uint64_t timer_id, bool can_overflow)
{
timers[timer_id].can_overflow = can_overflow;
timers[timer_id].can_target = can_target;
}

void Scheduler::set_timer_counter(uint64_t timer_id, uint64_t counter)
Expand Down
4 changes: 2 additions & 2 deletions src/core/scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct SchedulerTimer
int64_t last_update, pause_delta;
int callback_id;
bool paused;
bool can_overflow, can_target;
bool can_overflow;
};

class Scheduler
Expand Down Expand Up @@ -88,7 +88,7 @@ class Scheduler
void set_timer_target(uint64_t timer_id, uint64_t target);
void set_timer_clockrate(uint64_t timer_id, uint64_t clockrate);
void set_timer_pause(uint64_t timer_id, bool paused);
void set_timer_int_mask(uint64_t timer_id, bool can_overflow, bool can_target);
void set_timer_int_mask(uint64_t timer_id, bool can_overflow);

void update_cycle_counts();
void process_events();
Expand Down