From 3d541aaa73c0a4c209ead9a549e612f61bc813d5 Mon Sep 17 00:00:00 2001 From: Ty Lamontagne Date: Sun, 25 Jul 2021 19:00:09 -0400 Subject: [PATCH 1/2] Timers: 16 Bit Writes & Clear even when compare interrupts are disabled --- src/core/emulator.cpp | 5 +++++ src/core/scheduler.cpp | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/emulator.cpp b/src/core/emulator.cpp index fdc97c9f5..54f8a99ed 100644 --- a/src/core/emulator.cpp +++ b/src/core/emulator.cpp @@ -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; diff --git a/src/core/scheduler.cpp b/src/core/scheduler.cpp index e1c010ebc..751538ea7 100644 --- a/src/core/scheduler.cpp +++ b/src/core/scheduler.cpp @@ -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 From 610011a31800c2f58fdb9eb9f027593b58d831b9 Mon Sep 17 00:00:00 2001 From: Ty Lamontagne Date: Sun, 25 Jul 2021 19:42:43 -0400 Subject: [PATCH 2/2] Timers / Scheduler: Remove unnecessary can_target in SchedulerTimer The scheduler doesn't need to know if the timer (both IOP and EE) can target because the timer needs to reset regardless. --- src/core/ee/timers.cpp | 3 +-- src/core/iop/iop_timers.cpp | 14 ++++++++------ src/core/scheduler.cpp | 4 +--- src/core/scheduler.hpp | 4 ++-- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/core/ee/timers.cpp b/src/core/ee/timers.cpp index 740c743fe..53316f218 100644 --- a/src/core/ee/timers.cpp +++ b/src/core/ee/timers.cpp @@ -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); diff --git a/src/core/iop/iop_timers.cpp b/src/core/iop/iop_timers.cpp index 7c227e143..b69d64eb1 100644 --- a/src/core/iop/iop_timers.cpp +++ b/src/core/iop/iop_timers.cpp @@ -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) @@ -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) diff --git a/src/core/scheduler.cpp b/src/core/scheduler.cpp index 751538ea7..e29a89488 100644 --- a/src/core/scheduler.cpp +++ b/src/core/scheduler.cpp @@ -228,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; @@ -269,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) diff --git a/src/core/scheduler.hpp b/src/core/scheduler.hpp index 557ed40c4..5ba44feaf 100644 --- a/src/core/scheduler.hpp +++ b/src/core/scheduler.hpp @@ -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 @@ -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();