summaryrefslogtreecommitdiff
path: root/src/core/hle/svc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/svc.cpp')
-rw-r--r--src/core/hle/svc.cpp487
1 files changed, 296 insertions, 191 deletions
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 90c05cb74..441d8ce8d 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -9,6 +9,7 @@
9 9
10#include "core/mem_map.h" 10#include "core/mem_map.h"
11 11
12#include "core/hle/kernel/event.h"
12#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/mutex.h" 14#include "core/hle/kernel/mutex.h"
14#include "core/hle/kernel/thread.h" 15#include "core/hle/kernel/thread.h"
@@ -16,7 +17,6 @@
16#include "core/hle/function_wrappers.h" 17#include "core/hle/function_wrappers.h"
17#include "core/hle/svc.h" 18#include "core/hle/svc.h"
18#include "core/hle/service/service.h" 19#include "core/hle/service/service.h"
19#include "core/hle/kernel/thread.h"
20 20
21//////////////////////////////////////////////////////////////////////////////////////////////////// 21////////////////////////////////////////////////////////////////////////////////////////////////////
22// Namespace SVC 22// Namespace SVC
@@ -34,40 +34,32 @@ enum MapMemoryPermission {
34}; 34};
35 35
36/// Map application or GSP heap memory 36/// Map application or GSP heap memory
37Result ControlMemory(void* _outaddr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) { 37Result ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) {
38 u32* outaddr = (u32*)_outaddr; 38 DEBUG_LOG(SVC,"called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=%08X, permissions=0x%08X",
39 u32 virtual_address = 0x00000000;
40
41 DEBUG_LOG(SVC, "ControlMemory called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=%08X, permissions=0x%08X",
42 operation, addr0, addr1, size, permissions); 39 operation, addr0, addr1, size, permissions);
43 40
44 switch (operation) { 41 switch (operation) {
45 42
46 // Map normal heap memory 43 // Map normal heap memory
47 case MEMORY_OPERATION_HEAP: 44 case MEMORY_OPERATION_HEAP:
48 virtual_address = Memory::MapBlock_Heap(size, operation, permissions); 45 *out_addr = Memory::MapBlock_Heap(size, operation, permissions);
49 break; 46 break;
50 47
51 // Map GSP heap memory 48 // Map GSP heap memory
52 case MEMORY_OPERATION_GSP_HEAP: 49 case MEMORY_OPERATION_GSP_HEAP:
53 virtual_address = Memory::MapBlock_HeapGSP(size, operation, permissions); 50 *out_addr = Memory::MapBlock_HeapGSP(size, operation, permissions);
54 break; 51 break;
55 52
56 // Unknown ControlMemory operation 53 // Unknown ControlMemory operation
57 default: 54 default:
58 ERROR_LOG(SVC, "ControlMemory unknown operation=0x%08X", operation); 55 ERROR_LOG(SVC, "unknown operation=0x%08X", operation);
59 } 56 }
60 if (NULL != outaddr) {
61 *outaddr = virtual_address;
62 }
63 Core::g_app_core->SetReg(1, virtual_address);
64
65 return 0; 57 return 0;
66} 58}
67 59
68/// Maps a memory block to specified address 60/// Maps a memory block to specified address
69Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission) { 61Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission) {
70 DEBUG_LOG(SVC, "MapMemoryBlock called memblock=0x08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d", 62 DEBUG_LOG(SVC, "called memblock=0x08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d",
71 memblock, addr, mypermissions, otherpermission); 63 memblock, addr, mypermissions, otherpermission);
72 switch (mypermissions) { 64 switch (mypermissions) {
73 case MEMORY_PERMISSION_NORMAL: 65 case MEMORY_PERMISSION_NORMAL:
@@ -76,88 +68,146 @@ Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherper
76 Memory::MapBlock_Shared(memblock, addr, mypermissions); 68 Memory::MapBlock_Shared(memblock, addr, mypermissions);
77 break; 69 break;
78 default: 70 default:
79 ERROR_LOG(OSHLE, "MapMemoryBlock unknown permissions=0x%08X", mypermissions); 71 ERROR_LOG(OSHLE, "unknown permissions=0x%08X", mypermissions);
80 } 72 }
81 return 0; 73 return 0;
82} 74}
83 75
84/// Connect to an OS service given the port name, returns the handle to the port to out 76/// Connect to an OS service given the port name, returns the handle to the port to out
85Result ConnectToPort(void* out, const char* port_name) { 77Result ConnectToPort(Handle* out, const char* port_name) {
86 Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); 78 Service::Interface* service = Service::g_manager->FetchFromPortName(port_name);
87 if (service) { 79
88 Core::g_app_core->SetReg(1, service->GetHandle()); 80 DEBUG_LOG(SVC, "called port_name=%s", port_name);
89 } else { 81 _assert_msg_(KERNEL, (service != nullptr), "called, but service is not implemented!");
90 PanicYesNo("ConnectToPort called port_name=%s, but it is not implemented!", port_name); 82
91 } 83 *out = service->GetHandle();
92 DEBUG_LOG(SVC, "ConnectToPort called port_name=%s", port_name); 84
93 return 0; 85 return 0;
94} 86}
95 87
96/// Synchronize to an OS service 88/// Synchronize to an OS service
97Result SendSyncRequest(Handle handle) { 89Result SendSyncRequest(Handle handle) {
98 DEBUG_LOG(SVC, "SendSyncRequest called handle=0x%08X"); 90 Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle);
99 Service::Interface* service = Service::g_manager->FetchFromHandle(handle); 91
100 service->Sync(); 92 _assert_msg_(KERNEL, (object != nullptr), "called, but kernel object is nullptr!");
101 return 0; 93 DEBUG_LOG(SVC, "called handle=0x%08X(%s)", handle, object->GetTypeName());
94
95 bool wait = false;
96 Result res = object->SyncRequest(&wait);
97 if (wait) {
98 Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct?
99 }
100
101 return res;
102} 102}
103 103
104/// Close a handle 104/// Close a handle
105Result CloseHandle(Handle handle) { 105Result CloseHandle(Handle handle) {
106 // ImplementMe 106 // ImplementMe
107 DEBUG_LOG(SVC, "(UNIMPLEMENTED) CloseHandle called handle=0x%08X", handle); 107 ERROR_LOG(SVC, "(UNIMPLEMENTED) called handle=0x%08X", handle);
108 return 0; 108 return 0;
109} 109}
110 110
111/// Wait for a handle to synchronize, timeout after the specified nanoseconds 111/// Wait for a handle to synchronize, timeout after the specified nanoseconds
112Result WaitSynchronization1(Handle handle, s64 nano_seconds) { 112Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
113 DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronization1 called handle=0x%08X, nanoseconds=%d", 113 // TODO(bunnei): Do something with nano_seconds, currently ignoring this
114 handle, nano_seconds); 114 bool wait = false;
115 Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct? 115 bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated
116 return 0; 116
117 Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle);
118
119 DEBUG_LOG(SVC, "called handle=0x%08X(%s:%s), nanoseconds=%d", handle, object->GetTypeName(),
120 object->GetName(), nano_seconds);
121
122 _assert_msg_(KERNEL, (object != nullptr), "called, but kernel object is nullptr!");
123
124 Result res = object->WaitSynchronization(&wait);
125
126 // Check for next thread to schedule
127 if (wait) {
128 HLE::Reschedule(__func__);
129 return 0;
130 }
131
132 return res;
117} 133}
118 134
119/// Wait for the given handles to synchronize, timeout after the specified nanoseconds 135/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
120Result WaitSynchronizationN(void* _out, void* _handles, u32 handle_count, u32 wait_all, s64 nano_seconds) { 136Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all,
121 s32* out = (s32*)_out; 137 s64 nano_seconds) {
122 Handle* handles = (Handle*)_handles; 138 // TODO(bunnei): Do something with nano_seconds, currently ignoring this
139 bool unlock_all = true;
140 bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated
123 141
124 DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronizationN called handle_count=%d, wait_all=%s, nanoseconds=%d %s", 142 DEBUG_LOG(SVC, "called handle_count=%d, wait_all=%s, nanoseconds=%d",
125 handle_count, (wait_all ? "true" : "false"), nano_seconds); 143 handle_count, (wait_all ? "true" : "false"), nano_seconds);
126 144
127 for (u32 i = 0; i < handle_count; i++) { 145 // Iterate through each handle, synchronize kernel object
128 DEBUG_LOG(SVC, "\thandle[%d]=0x%08X", i, handles[i]); 146 for (s32 i = 0; i < handle_count; i++) {
147 bool wait = false;
148 Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handles[i]);
149
150 _assert_msg_(KERNEL, (object != nullptr), "called handle=0x%08X, but kernel object "
151 "is nullptr!", handles[i]);
152
153 DEBUG_LOG(SVC, "\thandle[%d] = 0x%08X(%s:%s)", i, handles[i], object->GetTypeName(),
154 object->GetName());
155
156 Result res = object->WaitSynchronization(&wait);
157
158 if (!wait && !wait_all) {
159 *out = i;
160 return 0;
161 } else {
162 unlock_all = false;
163 }
129 } 164 }
130 Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct? 165
166 if (wait_all && unlock_all) {
167 *out = handle_count;
168 return 0;
169 }
170
171 // Check for next thread to schedule
172 HLE::Reschedule(__func__);
173
131 return 0; 174 return 0;
132} 175}
133 176
134/// Create an address arbiter (to allocate access to shared resources) 177/// Create an address arbiter (to allocate access to shared resources)
135Result CreateAddressArbiter(void* arbiter) { 178Result CreateAddressArbiter(void* arbiter) {
136 // ImplementMe 179 ERROR_LOG(SVC, "(UNIMPLEMENTED) called");
137 DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateAddressArbiter called");
138 Core::g_app_core->SetReg(1, 0xFABBDADD); 180 Core::g_app_core->SetReg(1, 0xFABBDADD);
139 return 0; 181 return 0;
140} 182}
141 183
184/// Arbitrate address
185Result ArbitrateAddress(Handle arbiter, u32 addr, u32 _type, u32 value, s64 nanoseconds) {
186 ERROR_LOG(SVC, "(UNIMPLEMENTED) called");
187 ArbitrationType type = (ArbitrationType)_type;
188 Memory::Write32(addr, type);
189 return 0;
190}
191
142/// Used to output a message on a debug hardware unit - does nothing on a retail unit 192/// Used to output a message on a debug hardware unit - does nothing on a retail unit
143void OutputDebugString(const char* string) { 193void OutputDebugString(const char* string) {
144 NOTICE_LOG(SVC, "## OSDEBUG: %08X %s", Core::g_app_core->GetPC(), string); 194 OS_LOG(SVC, "%s", string);
145} 195}
146 196
147/// Get resource limit 197/// Get resource limit
148Result GetResourceLimit(void* resource_limit, Handle process) { 198Result GetResourceLimit(Handle* resource_limit, Handle process) {
149 // With regards to proceess values: 199 // With regards to proceess values:
150 // 0xFFFF8001 is a handle alias for the current KProcess, and 0xFFFF8000 is a handle alias for 200 // 0xFFFF8001 is a handle alias for the current KProcess, and 0xFFFF8000 is a handle alias for
151 // the current KThread. 201 // the current KThread.
152 DEBUG_LOG(SVC, "(UNIMPLEMENTED) GetResourceLimit called process=0x%08X", process); 202 *resource_limit = 0xDEADBEEF;
153 Core::g_app_core->SetReg(1, 0xDEADBEEF); 203 ERROR_LOG(SVC, "(UNIMPLEMENTED) called process=0x%08X", process);
154 return 0; 204 return 0;
155} 205}
156 206
157/// Get resource limit current values 207/// Get resource limit current values
158Result GetResourceLimitCurrentValues(void* _values, Handle resource_limit, void* names, s32 name_count) { 208Result GetResourceLimitCurrentValues(s64* values, Handle resource_limit, void* names,
159 //s64* values = (s64*)_values; 209 s32 name_count) {
160 DEBUG_LOG(SVC, "(UNIMPLEMENTED) GetResourceLimitCurrentValues called resource_limit=%08X, names=%s, name_count=%d", 210 ERROR_LOG(SVC, "(UNIMPLEMENTED) called resource_limit=%08X, names=%s, name_count=%d",
161 resource_limit, names, name_count); 211 resource_limit, names, name_count);
162 Memory::Write32(Core::g_app_core->GetReg(0), 0); // Normmatt: Set used memory to 0 for now 212 Memory::Write32(Core::g_app_core->GetReg(0), 0); // Normmatt: Set used memory to 0 for now
163 return 0; 213 return 0;
@@ -180,179 +230,234 @@ Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 p
180 230
181 Core::g_app_core->SetReg(1, thread); 231 Core::g_app_core->SetReg(1, thread);
182 232
183 DEBUG_LOG(SVC, "CreateThread called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " 233 DEBUG_LOG(SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
184 "threadpriority=0x%08X, processorid=0x%08X : created handle 0x%08X", entry_point, 234 "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", entry_point,
185 name.c_str(), arg, stack_top, priority, processor_id, thread); 235 name.c_str(), arg, stack_top, priority, processor_id, thread);
186 236
187 return 0; 237 return 0;
188} 238}
189 239
240/// Called when a thread exits
241u32 ExitThread() {
242 Handle thread = Kernel::GetCurrentThreadHandle();
243
244 DEBUG_LOG(SVC, "called, pc=0x%08X", Core::g_app_core->GetPC()); // PC = 0x0010545C
245
246 Kernel::StopThread(thread, __func__);
247 HLE::Reschedule(__func__);
248 return 0;
249}
250
251/// Gets the priority for the specified thread
252Result GetThreadPriority(s32* priority, Handle handle) {
253 *priority = Kernel::GetThreadPriority(handle);
254 return 0;
255}
256
257/// Sets the priority for the specified thread
258Result SetThreadPriority(Handle handle, s32 priority) {
259 return Kernel::SetThreadPriority(handle, priority);
260}
261
190/// Create a mutex 262/// Create a mutex
191Result CreateMutex(void* _mutex, u32 initial_locked) { 263Result CreateMutex(Handle* mutex, u32 initial_locked) {
192 Handle* mutex = (Handle*)_mutex;
193 *mutex = Kernel::CreateMutex((initial_locked != 0)); 264 *mutex = Kernel::CreateMutex((initial_locked != 0));
194 Core::g_app_core->SetReg(1, *mutex); 265 DEBUG_LOG(SVC, "called initial_locked=%s : created handle=0x%08X",
195 DEBUG_LOG(SVC, "CreateMutex called initial_locked=%s : created handle 0x%08X",
196 initial_locked ? "true" : "false", *mutex); 266 initial_locked ? "true" : "false", *mutex);
197 return 0; 267 return 0;
198} 268}
199 269
200/// Release a mutex 270/// Release a mutex
201Result ReleaseMutex(Handle handle) { 271Result ReleaseMutex(Handle handle) {
202 DEBUG_LOG(SVC, "ReleaseMutex called handle=0x%08X", handle); 272 DEBUG_LOG(SVC, "called handle=0x%08X", handle);
273 _assert_msg_(KERNEL, (handle != 0), "called, but handle is nullptr!");
203 Kernel::ReleaseMutex(handle); 274 Kernel::ReleaseMutex(handle);
204 return 0; 275 return 0;
205} 276}
206 277
207/// Get current thread ID 278/// Get current thread ID
208Result GetThreadId(void* thread_id, u32 thread) { 279Result GetThreadId(u32* thread_id, Handle thread) {
209 DEBUG_LOG(SVC, "(UNIMPLEMENTED) GetThreadId called thread=0x%08X", thread); 280 ERROR_LOG(SVC, "(UNIMPLEMENTED) called thread=0x%08X", thread);
210 return 0; 281 return 0;
211} 282}
212 283
213/// Query memory 284/// Query memory
214Result QueryMemory(void *_info, void *_out, u32 addr) { 285Result QueryMemory(void* info, void* out, u32 addr) {
215 MemoryInfo* info = (MemoryInfo*) _info; 286 ERROR_LOG(SVC, "(UNIMPLEMENTED) called addr=0x%08X", addr);
216 PageInfo* out = (PageInfo*) _out;
217 DEBUG_LOG(SVC, "(UNIMPLEMENTED) QueryMemory called addr=0x%08X", addr);
218 return 0; 287 return 0;
219} 288}
220 289
221/// Create an event 290/// Create an event
222Result CreateEvent(void* _event, u32 reset_type) { 291Result CreateEvent(Handle* evt, u32 reset_type) {
223 Handle* event = (Handle*)_event; 292 *evt = Kernel::CreateEvent((ResetType)reset_type);
224 DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateEvent called reset_type=0x%08X", reset_type); 293 DEBUG_LOG(SVC, "called reset_type=0x%08X : created handle=0x%08X",
225 Core::g_app_core->SetReg(1, 0xBADC0DE0); 294 reset_type, *evt);
295 return 0;
296}
297
298/// Duplicates a kernel handle
299Result DuplicateHandle(Handle* out, Handle handle) {
300 DEBUG_LOG(SVC, "called handle=0x%08X", handle);
301
302 // Translate kernel handles -> real handles
303 if (handle == Kernel::CurrentThread) {
304 handle = Kernel::GetCurrentThreadHandle();
305 }
306 _assert_msg_(KERNEL, (handle != Kernel::CurrentProcess),
307 "(UNIMPLEMENTED) process handle duplication!");
308
309 // TODO(bunnei): FixMe - This is a hack to return the handle that we were asked to duplicate.
310 *out = handle;
311
226 return 0; 312 return 0;
227} 313}
228 314
315/// Signals an event
316Result SignalEvent(Handle evt) {
317 Result res = Kernel::SignalEvent(evt);
318 DEBUG_LOG(SVC, "called event=0x%08X", evt);
319 return res;
320}
321
322/// Clears an event
323Result ClearEvent(Handle evt) {
324 Result res = Kernel::ClearEvent(evt);
325 DEBUG_LOG(SVC, "called event=0x%08X", evt);
326 return res;
327}
328
329/// Sleep the current thread
330void SleepThread(s64 nanoseconds) {
331 DEBUG_LOG(SVC, "called nanoseconds=%d", nanoseconds);
332}
333
229const HLE::FunctionDef SVC_Table[] = { 334const HLE::FunctionDef SVC_Table[] = {
230 {0x00, NULL, "Unknown"}, 335 {0x00, nullptr, "Unknown"},
231 {0x01, WrapI_VUUUUU<ControlMemory>, "ControlMemory"}, 336 {0x01, HLE::Wrap<ControlMemory>, "ControlMemory"},
232 {0x02, WrapI_VVU<QueryMemory>, "QueryMemory"}, 337 {0x02, HLE::Wrap<QueryMemory>, "QueryMemory"},
233 {0x03, NULL, "ExitProcess"}, 338 {0x03, nullptr, "ExitProcess"},
234 {0x04, NULL, "GetProcessAffinityMask"}, 339 {0x04, nullptr, "GetProcessAffinityMask"},
235 {0x05, NULL, "SetProcessAffinityMask"}, 340 {0x05, nullptr, "SetProcessAffinityMask"},
236 {0x06, NULL, "GetProcessIdealProcessor"}, 341 {0x06, nullptr, "GetProcessIdealProcessor"},
237 {0x07, NULL, "SetProcessIdealProcessor"}, 342 {0x07, nullptr, "SetProcessIdealProcessor"},
238 {0x08, WrapI_UUUUU<CreateThread>, "CreateThread"}, 343 {0x08, HLE::Wrap<CreateThread>, "CreateThread"},
239 {0x09, NULL, "ExitThread"}, 344 {0x09, HLE::Wrap<ExitThread>, "ExitThread"},
240 {0x0A, NULL, "SleepThread"}, 345 {0x0A, HLE::Wrap<SleepThread>, "SleepThread"},
241 {0x0B, NULL, "GetThreadPriority"}, 346 {0x0B, HLE::Wrap<GetThreadPriority>, "GetThreadPriority"},
242 {0x0C, NULL, "SetThreadPriority"}, 347 {0x0C, HLE::Wrap<SetThreadPriority>, "SetThreadPriority"},
243 {0x0D, NULL, "GetThreadAffinityMask"}, 348 {0x0D, nullptr, "GetThreadAffinityMask"},
244 {0x0E, NULL, "SetThreadAffinityMask"}, 349 {0x0E, nullptr, "SetThreadAffinityMask"},
245 {0x0F, NULL, "GetThreadIdealProcessor"}, 350 {0x0F, nullptr, "GetThreadIdealProcessor"},
246 {0x10, NULL, "SetThreadIdealProcessor"}, 351 {0x10, nullptr, "SetThreadIdealProcessor"},
247 {0x11, NULL, "GetCurrentProcessorNumber"}, 352 {0x11, nullptr, "GetCurrentProcessorNumber"},
248 {0x12, NULL, "Run"}, 353 {0x12, nullptr, "Run"},
249 {0x13, WrapI_VU<CreateMutex>, "CreateMutex"}, 354 {0x13, HLE::Wrap<CreateMutex>, "CreateMutex"},
250 {0x14, WrapI_U<ReleaseMutex>, "ReleaseMutex"}, 355 {0x14, HLE::Wrap<ReleaseMutex>, "ReleaseMutex"},
251 {0x15, NULL, "CreateSemaphore"}, 356 {0x15, nullptr, "CreateSemaphore"},
252 {0x16, NULL, "ReleaseSemaphore"}, 357 {0x16, nullptr, "ReleaseSemaphore"},
253 {0x17, WrapI_VU<CreateEvent>, "CreateEvent"}, 358 {0x17, HLE::Wrap<CreateEvent>, "CreateEvent"},
254 {0x18, NULL, "SignalEvent"}, 359 {0x18, HLE::Wrap<SignalEvent>, "SignalEvent"},
255 {0x19, NULL, "ClearEvent"}, 360 {0x19, HLE::Wrap<ClearEvent>, "ClearEvent"},
256 {0x1A, NULL, "CreateTimer"}, 361 {0x1A, nullptr, "CreateTimer"},
257 {0x1B, NULL, "SetTimer"}, 362 {0x1B, nullptr, "SetTimer"},
258 {0x1C, NULL, "CancelTimer"}, 363 {0x1C, nullptr, "CancelTimer"},
259 {0x1D, NULL, "ClearTimer"}, 364 {0x1D, nullptr, "ClearTimer"},
260 {0x1E, NULL, "CreateMemoryBlock"}, 365 {0x1E, nullptr, "CreateMemoryBlock"},
261 {0x1F, WrapI_UUUU<MapMemoryBlock>, "MapMemoryBlock"}, 366 {0x1F, HLE::Wrap<MapMemoryBlock>, "MapMemoryBlock"},
262 {0x20, NULL, "UnmapMemoryBlock"}, 367 {0x20, nullptr, "UnmapMemoryBlock"},
263 {0x21, WrapI_V<CreateAddressArbiter>, "CreateAddressArbiter"}, 368 {0x21, HLE::Wrap<CreateAddressArbiter>, "CreateAddressArbiter"},
264 {0x22, NULL, "ArbitrateAddress"}, 369 {0x22, HLE::Wrap<ArbitrateAddress>, "ArbitrateAddress"},
265 {0x23, WrapI_U<CloseHandle>, "CloseHandle"}, 370 {0x23, HLE::Wrap<CloseHandle>, "CloseHandle"},
266 {0x24, WrapI_US64<WaitSynchronization1>, "WaitSynchronization1"}, 371 {0x24, HLE::Wrap<WaitSynchronization1>, "WaitSynchronization1"},
267 {0x25, WrapI_VVUUS64<WaitSynchronizationN>, "WaitSynchronizationN"}, 372 {0x25, HLE::Wrap<WaitSynchronizationN>, "WaitSynchronizationN"},
268 {0x26, NULL, "SignalAndWait"}, 373 {0x26, nullptr, "SignalAndWait"},
269 {0x27, NULL, "DuplicateHandle"}, 374 {0x27, HLE::Wrap<DuplicateHandle>, "DuplicateHandle"},
270 {0x28, NULL, "GetSystemTick"}, 375 {0x28, nullptr, "GetSystemTick"},
271 {0x29, NULL, "GetHandleInfo"}, 376 {0x29, nullptr, "GetHandleInfo"},
272 {0x2A, NULL, "GetSystemInfo"}, 377 {0x2A, nullptr, "GetSystemInfo"},
273 {0x2B, NULL, "GetProcessInfo"}, 378 {0x2B, nullptr, "GetProcessInfo"},
274 {0x2C, NULL, "GetThreadInfo"}, 379 {0x2C, nullptr, "GetThreadInfo"},
275 {0x2D, WrapI_VC<ConnectToPort>, "ConnectToPort"}, 380 {0x2D, HLE::Wrap<ConnectToPort>, "ConnectToPort"},
276 {0x2E, NULL, "SendSyncRequest1"}, 381 {0x2E, nullptr, "SendSyncRequest1"},
277 {0x2F, NULL, "SendSyncRequest2"}, 382 {0x2F, nullptr, "SendSyncRequest2"},
278 {0x30, NULL, "SendSyncRequest3"}, 383 {0x30, nullptr, "SendSyncRequest3"},
279 {0x31, NULL, "SendSyncRequest4"}, 384 {0x31, nullptr, "SendSyncRequest4"},
280 {0x32, WrapI_U<SendSyncRequest>, "SendSyncRequest"}, 385 {0x32, HLE::Wrap<SendSyncRequest>, "SendSyncRequest"},
281 {0x33, NULL, "OpenProcess"}, 386 {0x33, nullptr, "OpenProcess"},
282 {0x34, NULL, "OpenThread"}, 387 {0x34, nullptr, "OpenThread"},
283 {0x35, NULL, "GetProcessId"}, 388 {0x35, nullptr, "GetProcessId"},
284 {0x36, NULL, "GetProcessIdOfThread"}, 389 {0x36, nullptr, "GetProcessIdOfThread"},
285 {0x37, WrapI_VU<GetThreadId>, "GetThreadId"}, 390 {0x37, HLE::Wrap<GetThreadId>, "GetThreadId"},
286 {0x38, WrapI_VU<GetResourceLimit>, "GetResourceLimit"}, 391 {0x38, HLE::Wrap<GetResourceLimit>, "GetResourceLimit"},
287 {0x39, NULL, "GetResourceLimitLimitValues"}, 392 {0x39, nullptr, "GetResourceLimitLimitValues"},
288 {0x3A, WrapI_VUVI<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"}, 393 {0x3A, HLE::Wrap<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"},
289 {0x3B, NULL, "GetThreadContext"}, 394 {0x3B, nullptr, "GetThreadContext"},
290 {0x3C, NULL, "Break"}, 395 {0x3C, nullptr, "Break"},
291 {0x3D, WrapV_C<OutputDebugString>, "OutputDebugString"}, 396 {0x3D, HLE::Wrap<OutputDebugString>, "OutputDebugString"},
292 {0x3E, NULL, "ControlPerformanceCounter"}, 397 {0x3E, nullptr, "ControlPerformanceCounter"},
293 {0x3F, NULL, "Unknown"}, 398 {0x3F, nullptr, "Unknown"},
294 {0x40, NULL, "Unknown"}, 399 {0x40, nullptr, "Unknown"},
295 {0x41, NULL, "Unknown"}, 400 {0x41, nullptr, "Unknown"},
296 {0x42, NULL, "Unknown"}, 401 {0x42, nullptr, "Unknown"},
297 {0x43, NULL, "Unknown"}, 402 {0x43, nullptr, "Unknown"},
298 {0x44, NULL, "Unknown"}, 403 {0x44, nullptr, "Unknown"},
299 {0x45, NULL, "Unknown"}, 404 {0x45, nullptr, "Unknown"},
300 {0x46, NULL, "Unknown"}, 405 {0x46, nullptr, "Unknown"},
301 {0x47, NULL, "CreatePort"}, 406 {0x47, nullptr, "CreatePort"},
302 {0x48, NULL, "CreateSessionToPort"}, 407 {0x48, nullptr, "CreateSessionToPort"},
303 {0x49, NULL, "CreateSession"}, 408 {0x49, nullptr, "CreateSession"},
304 {0x4A, NULL, "AcceptSession"}, 409 {0x4A, nullptr, "AcceptSession"},
305 {0x4B, NULL, "ReplyAndReceive1"}, 410 {0x4B, nullptr, "ReplyAndReceive1"},
306 {0x4C, NULL, "ReplyAndReceive2"}, 411 {0x4C, nullptr, "ReplyAndReceive2"},
307 {0x4D, NULL, "ReplyAndReceive3"}, 412 {0x4D, nullptr, "ReplyAndReceive3"},
308 {0x4E, NULL, "ReplyAndReceive4"}, 413 {0x4E, nullptr, "ReplyAndReceive4"},
309 {0x4F, NULL, "ReplyAndReceive"}, 414 {0x4F, nullptr, "ReplyAndReceive"},
310 {0x50, NULL, "BindInterrupt"}, 415 {0x50, nullptr, "BindInterrupt"},
311 {0x51, NULL, "UnbindInterrupt"}, 416 {0x51, nullptr, "UnbindInterrupt"},
312 {0x52, NULL, "InvalidateProcessDataCache"}, 417 {0x52, nullptr, "InvalidateProcessDataCache"},
313 {0x53, NULL, "StoreProcessDataCache"}, 418 {0x53, nullptr, "StoreProcessDataCache"},
314 {0x54, NULL, "FlushProcessDataCache"}, 419 {0x54, nullptr, "FlushProcessDataCache"},
315 {0x55, NULL, "StartInterProcessDma"}, 420 {0x55, nullptr, "StartInterProcessDma"},
316 {0x56, NULL, "StopDma"}, 421 {0x56, nullptr, "StopDma"},
317 {0x57, NULL, "GetDmaState"}, 422 {0x57, nullptr, "GetDmaState"},
318 {0x58, NULL, "RestartDma"}, 423 {0x58, nullptr, "RestartDma"},
319 {0x59, NULL, "Unknown"}, 424 {0x59, nullptr, "Unknown"},
320 {0x5A, NULL, "Unknown"}, 425 {0x5A, nullptr, "Unknown"},
321 {0x5B, NULL, "Unknown"}, 426 {0x5B, nullptr, "Unknown"},
322 {0x5C, NULL, "Unknown"}, 427 {0x5C, nullptr, "Unknown"},
323 {0x5D, NULL, "Unknown"}, 428 {0x5D, nullptr, "Unknown"},
324 {0x5E, NULL, "Unknown"}, 429 {0x5E, nullptr, "Unknown"},
325 {0x5F, NULL, "Unknown"}, 430 {0x5F, nullptr, "Unknown"},
326 {0x60, NULL, "DebugActiveProcess"}, 431 {0x60, nullptr, "DebugActiveProcess"},
327 {0x61, NULL, "BreakDebugProcess"}, 432 {0x61, nullptr, "BreakDebugProcess"},
328 {0x62, NULL, "TerminateDebugProcess"}, 433 {0x62, nullptr, "TerminateDebugProcess"},
329 {0x63, NULL, "GetProcessDebugEvent"}, 434 {0x63, nullptr, "GetProcessDebugEvent"},
330 {0x64, NULL, "ContinueDebugEvent"}, 435 {0x64, nullptr, "ContinueDebugEvent"},
331 {0x65, NULL, "GetProcessList"}, 436 {0x65, nullptr, "GetProcessList"},
332 {0x66, NULL, "GetThreadList"}, 437 {0x66, nullptr, "GetThreadList"},
333 {0x67, NULL, "GetDebugThreadContext"}, 438 {0x67, nullptr, "GetDebugThreadContext"},
334 {0x68, NULL, "SetDebugThreadContext"}, 439 {0x68, nullptr, "SetDebugThreadContext"},
335 {0x69, NULL, "QueryDebugProcessMemory"}, 440 {0x69, nullptr, "QueryDebugProcessMemory"},
336 {0x6A, NULL, "ReadProcessMemory"}, 441 {0x6A, nullptr, "ReadProcessMemory"},
337 {0x6B, NULL, "WriteProcessMemory"}, 442 {0x6B, nullptr, "WriteProcessMemory"},
338 {0x6C, NULL, "SetHardwareBreakPoint"}, 443 {0x6C, nullptr, "SetHardwareBreakPoint"},
339 {0x6D, NULL, "GetDebugThreadParam"}, 444 {0x6D, nullptr, "GetDebugThreadParam"},
340 {0x6E, NULL, "Unknown"}, 445 {0x6E, nullptr, "Unknown"},
341 {0x6F, NULL, "Unknown"}, 446 {0x6F, nullptr, "Unknown"},
342 {0x70, NULL, "ControlProcessMemory"}, 447 {0x70, nullptr, "ControlProcessMemory"},
343 {0x71, NULL, "MapProcessMemory"}, 448 {0x71, nullptr, "MapProcessMemory"},
344 {0x72, NULL, "UnmapProcessMemory"}, 449 {0x72, nullptr, "UnmapProcessMemory"},
345 {0x73, NULL, "Unknown"}, 450 {0x73, nullptr, "Unknown"},
346 {0x74, NULL, "Unknown"}, 451 {0x74, nullptr, "Unknown"},
347 {0x75, NULL, "Unknown"}, 452 {0x75, nullptr, "Unknown"},
348 {0x76, NULL, "TerminateProcess"}, 453 {0x76, nullptr, "TerminateProcess"},
349 {0x77, NULL, "Unknown"}, 454 {0x77, nullptr, "Unknown"},
350 {0x78, NULL, "CreateResourceLimit"}, 455 {0x78, nullptr, "CreateResourceLimit"},
351 {0x79, NULL, "Unknown"}, 456 {0x79, nullptr, "Unknown"},
352 {0x7A, NULL, "Unknown"}, 457 {0x7A, nullptr, "Unknown"},
353 {0x7B, NULL, "Unknown"}, 458 {0x7B, nullptr, "Unknown"},
354 {0x7C, NULL, "KernelSetState"}, 459 {0x7C, nullptr, "KernelSetState"},
355 {0x7D, NULL, "QueryProcessMemory"}, 460 {0x7D, nullptr, "QueryProcessMemory"},
356}; 461};
357 462
358void Register() { 463void Register() {