diff --git a/kernel/ps4_event_flag.pas b/kernel/ps4_event_flag.pas index 02bd169..d64370d 100644 --- a/kernel/ps4_event_flag.pas +++ b/kernel/ps4_event_flag.pas @@ -81,6 +81,10 @@ function ps4_sceKernelSetEventFlag(ef:SceKernelEventFlag;bitPattern:QWORD):Integ function ps4_sceKernelClearEventFlag(ef:SceKernelEventFlag;bitPattern:QWORD):Integer; SysV_ABI_CDecl; function ps4_sceKernelDeleteEventFlag(ef:SceKernelEventFlag):Integer; SysV_ABI_CDecl; +function ps4_sceKernelCancelEventFlag(ef:SceKernelEventFlag; + bitPattern:QWORD; + pNumWaitThreads:Pinteger):Integer; SysV_ABI_CDecl; + implementation uses @@ -428,7 +432,7 @@ end; function ps4_sceKernelSetEventFlag(ef:SceKernelEventFlag;bitPattern:QWORD):Integer; SysV_ABI_CDecl; var node:pwef_node; - prev,bits:QWORD; + bits:QWORD; attr:DWORD; begin Result:=ef_enter(ef); @@ -548,11 +552,72 @@ begin Result:=0; end; +function ps4_sceKernelCancelEventFlag(ef:SceKernelEventFlag; + bitPattern:QWORD; + pNumWaitThreads:Pinteger):Integer; SysV_ABI_CDecl; +var + node:pwef_node; + attr:DWORD; + count:Integer; +begin + Result:=ef_enter(ef); + if (Result<>0) then Exit(SCE_KERNEL_ERROR_ESRCH); + + _sig_lock; + + Writeln('>sceKernelCancelEventFlag:',HexStr(ef),':',ef^.name); + + spin_lock(ef^.lock_list); + + attr:=ef^.attr; + + count:=0; + + //cancel all + if _is_single(attr) then + begin + fetch_or(ef^.bitPattern,bitPattern); + + ef^.single.ret:=SCE_KERNEL_ERROR_ECANCELED; + NtQueueApcThread(ef^.single.thread,@_apc_null,0,nil,0); + + count:=1; + end else + begin + fetch_or(ef^.bitPattern,bitPattern); + + node:=ef^.list.pHead; + While (node<>nil) do + begin + if (node^.ret=1) then + begin + node^.ResultPat:=ef^.bitPattern; + node^.ret:=SCE_KERNEL_ERROR_ECANCELED; + NtQueueApcThread(node^.thread,@_apc_null,0,nil,0); + + Inc(count); + end; + node:=node^.pNext; + end; + end; + + spin_unlock(ef^.lock_list); + + _sig_unlock; + + if (pNumWaitThreads<>nil) then + begin + pNumWaitThreads^:=count; + end; + + System.InterlockedDecrement(ef^.refs); + ef_leave(ef); + Result:=0; +end; + { int sceKernelPollEventFlag(SceKernelEventFlag ef, uint64_t bitPattern, uint32_t waitMode, uint64_t *pResultPat); -int sceKernelCancelEventFlag(SceKernelEventFlag ef, uint64_t setPattern, - int *pNumWaitThreads); } end. diff --git a/kernel/ps4_libkernel.pas b/kernel/ps4_libkernel.pas index 509c165..a42a125 100644 --- a/kernel/ps4_libkernel.pas +++ b/kernel/ps4_libkernel.pas @@ -1147,6 +1147,7 @@ begin lib^.set_proc($20E9D2BC7CEABBA0,@ps4_sceKernelSetEventFlag); lib^.set_proc($EEE8411564404BAD,@ps4_sceKernelClearEventFlag); lib^.set_proc($F26AA5F4E7109DDE,@ps4_sceKernelDeleteEventFlag); + lib^.set_proc($3D992EE19AD726A8,@ps4_sceKernelCancelEventFlag); //event_flag diff --git a/kernel/ps4_map_mm.pas b/kernel/ps4_map_mm.pas index 16f4f4a..8d01d7d 100644 --- a/kernel/ps4_map_mm.pas +++ b/kernel/ps4_map_mm.pas @@ -343,7 +343,7 @@ end; function ps4_sceKernelGetDirectMemorySize:Int64; SysV_ABI_CDecl; begin - Result:=SCE_KERNEL_MAIN_DMEM_SIZE; + Result:=SCE_KERNEL_MAIN_DMEM_SIZE-(448*1024*1024); end; function ps4_getpagesize:Integer; SysV_ABI_CDecl; @@ -441,7 +441,7 @@ var begin Result:=EINVAL; - if (physAddrOut=nil) or (sizeOut=nil) or (searchEnd<=searchStart) then Exit; + if (searchEnd<=searchStart) then Exit; if (searchEnd>SCE_KERNEL_MAIN_DMEM_SIZE) then Exit;