summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp8
-rw-r--r--src/core/hle/ipc.h6
-rw-r--r--src/core/hle/kernel/timer.cpp39
-rw-r--r--src/core/hle/kernel/timer.h8
-rw-r--r--src/core/hle/service/hid/hid.cpp7
-rw-r--r--src/core/hle/service/ir/ir_u.cpp2
-rw-r--r--src/core/hle/service/nim/nim.cpp2
-rw-r--r--src/core/hle/svc.cpp5
9 files changed, 51 insertions, 27 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index da3d024bb..8334fece9 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -208,6 +208,7 @@ set(HEADERS
file_sys/archive_systemsavedata.h
file_sys/directory_backend.h
file_sys/disk_archive.h
+ file_sys/errors.h
file_sys/file_backend.h
file_sys/ivfc_archive.h
file_sys/path_parser.h
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 67c45640a..273bc8167 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -3928,13 +3928,13 @@ SXTB16_INST : {
if (inst_cream->Rn == 15) {
u32 lo = (u32)(s8)rm_val;
u32 hi = (u32)(s8)(rm_val >> 16);
- RD = (lo | (hi << 16));
+ RD = (lo & 0xFFFF) | (hi << 16);
}
// SXTAB16
else {
- u32 lo = (rn_val & 0xFFFF) + (u32)(s8)(rm_val & 0xFF);
- u32 hi = ((rn_val >> 16) & 0xFFFF) + (u32)(s8)((rm_val >> 16) & 0xFF);
- RD = (lo | (hi << 16));
+ u32 lo = rn_val + (u32)(s8)(rm_val & 0xFF);
+ u32 hi = (rn_val >> 16) + (u32)(s8)((rm_val >> 16) & 0xFF);
+ RD = (lo & 0xFFFF) | (hi << 16);
}
}
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h
index 4535b61c0..bbaae8b79 100644
--- a/src/core/hle/ipc.h
+++ b/src/core/hle/ipc.h
@@ -77,7 +77,7 @@ union Header {
*/
inline u32 MakeHeader(u16 command_id, unsigned int normal_params_size,
unsigned int translate_params_size) {
- Header header;
+ Header header{};
header.command_id.Assign(command_id);
header.normal_params_size.Assign(normal_params_size);
header.translate_params_size.Assign(translate_params_size);
@@ -112,7 +112,7 @@ union StaticBufferDescInfo {
};
inline u32 StaticBufferDesc(u32 size, u8 buffer_id) {
- StaticBufferDescInfo info;
+ StaticBufferDescInfo info{};
info.descriptor_type.Assign(StaticBuffer);
info.buffer_id.Assign(buffer_id);
info.size.Assign(size);
@@ -150,7 +150,7 @@ union MappedBufferDescInfo {
};
inline u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) {
- MappedBufferDescInfo info;
+ MappedBufferDescInfo info{};
info.flags.Assign(MappedBuffer);
info.perms.Assign(perms);
info.size.Assign(size);
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 60537f355..c42003e9d 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -52,9 +52,14 @@ void Timer::Set(s64 initial, s64 interval) {
initial_delay = initial;
interval_delay = interval;
- u64 initial_microseconds = initial / 1000;
- CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type,
- callback_handle);
+ if (initial == 0) {
+ // Immediately invoke the callback
+ Signal(0);
+ } else {
+ u64 initial_microseconds = initial / 1000;
+ CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type,
+ callback_handle);
+ }
}
void Timer::Cancel() {
@@ -72,6 +77,20 @@ void Timer::WakeupAllWaitingThreads() {
signaled = false;
}
+void Timer::Signal(int cycles_late) {
+ LOG_TRACE(Kernel, "Timer %08" PRIx64 " fired", timer_handle);
+
+ // Resume all waiting threads
+ WakeupAllWaitingThreads();
+
+ if (interval_delay != 0) {
+ // Reschedule the timer with the interval delay
+ u64 interval_microseconds = interval_delay / 1000;
+ CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late,
+ timer_callback_event_type, callback_handle);
+ }
+}
+
/// The timer callback event, called when a timer is fired
static void TimerCallback(u64 timer_handle, int cycles_late) {
SharedPtr<Timer> timer =
@@ -82,19 +101,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
return;
}
- LOG_TRACE(Kernel, "Timer %08" PRIx64 " fired", timer_handle);
-
- timer->signaled = true;
-
- // Resume all waiting threads
- timer->WakeupAllWaitingThreads();
-
- if (timer->interval_delay != 0) {
- // Reschedule the timer with the interval delay
- u64 interval_microseconds = timer->interval_delay / 1000;
- CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late,
- timer_callback_event_type, timer_handle);
- }
+ timer->Signal(cycles_late);
}
void TimersInit() {
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h
index c174f5664..b0f818933 100644
--- a/src/core/hle/kernel/timer.h
+++ b/src/core/hle/kernel/timer.h
@@ -54,6 +54,14 @@ public:
void Cancel();
void Clear();
+ /**
+ * Signals the timer, waking up any waiting threads and rescheduling it
+ * for the next interval.
+ * This method should not be called from outside the timer callback handler,
+ * lest multiple callback events get scheduled.
+ */
+ void Signal(int cycles_late);
+
private:
Timer();
~Timer() override;
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index f14ab3811..fb3acb507 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -32,8 +32,8 @@ static u32 next_touch_index;
static u32 next_accelerometer_index;
static u32 next_gyroscope_index;
-static int enable_accelerometer_count = 0; // positive means enabled
-static int enable_gyroscope_count = 0; // positive means enabled
+static int enable_accelerometer_count; // positive means enabled
+static int enable_gyroscope_count; // positive means enabled
static int pad_update_event;
static int accelerometer_update_event;
@@ -323,6 +323,9 @@ void Init() {
next_accelerometer_index = 0;
next_gyroscope_index = 0;
+ enable_accelerometer_count = 0;
+ enable_gyroscope_count = 0;
+
// Create event handles
event_pad_or_touch_1 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch1");
event_pad_or_touch_2 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch2");
diff --git a/src/core/hle/service/ir/ir_u.cpp b/src/core/hle/service/ir/ir_u.cpp
index 429615f31..ce00d5732 100644
--- a/src/core/hle/service/ir/ir_u.cpp
+++ b/src/core/hle/service/ir/ir_u.cpp
@@ -27,7 +27,7 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00100000, nullptr, "GetErrorStatus"},
{0x00110040, nullptr, "SetSleepModeActive"},
{0x00120040, nullptr, "SetSleepModeState"},
- // clang-format off
+ // clang-format on
};
IR_U_Interface::IR_U_Interface() {
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index 0be94322c..63c334cb2 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -19,7 +19,7 @@ void CheckSysUpdateAvailable(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw;
cmd_buff[2] = 0; // No update available
- LOG_WARNING(Service_NWM, "(STUBBED) called");
+ LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void Init() {
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 96db39ad9..1baa80671 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -837,6 +837,11 @@ static ResultCode SetTimer(Kernel::Handle handle, s64 initial, s64 interval) {
LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle);
+ if (initial < 0 || interval < 0) {
+ return ResultCode(ErrorDescription::OutOfRange, ErrorModule::Kernel,
+ ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
+ }
+
SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle);
if (timer == nullptr)
return ERR_INVALID_HANDLE;