diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 8 | ||||
-rw-r--r-- | src/core/hle/ipc.h | 6 | ||||
-rw-r--r-- | src/core/hle/kernel/timer.cpp | 39 | ||||
-rw-r--r-- | src/core/hle/kernel/timer.h | 8 | ||||
-rw-r--r-- | src/core/hle/service/hid/hid.cpp | 7 | ||||
-rw-r--r-- | src/core/hle/service/ir/ir_u.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/nim/nim.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/svc.cpp | 5 |
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; |