Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Unknown W. Brackets 2012-11-12 01:35:38 -08:00
commit a0cacc7eb9
8 changed files with 125 additions and 108 deletions

View File

@ -48,6 +48,10 @@ template<int func()> void WrapI_V() {
RETURN(retval);
}
template<u32 func(int)> void WrapU_I() {
u32 retval = func(PARAM(0));
RETURN(retval);
}
template<int func(int)> void WrapI_I() {
int retval = func(PARAM(0));
@ -75,6 +79,11 @@ template<u32 func(u32, u32)> void WrapU_UU() {
RETURN(retval);
}
template<u32 func(int, u32)> void WrapU_IU() {
int retval = func(PARAM(0), PARAM(1));
RETURN(retval);
}
template<int func(int, u32)> void WrapI_IU() {
int retval = func(PARAM(0), PARAM(1));
RETURN(retval);
@ -104,6 +113,11 @@ template<int func(const char *, u32)> void WrapI_CU() {
RETURN(retval);
}
template<int func(const char *, u32, u32, u32)> void WrapI_CUUU() {
int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3));
RETURN(retval);
}
template<u32 func(const char *, u32)> void WrapU_CU() {
int retval = func(Memory::GetCharPointer(PARAM(0)), PARAM(1));
RETURN((u32)retval);
@ -128,6 +142,10 @@ template<void func(int, u32, u32)> void WrapV_IUU() {
func(PARAM(0), PARAM(1), PARAM(2));
}
template<void func(int, u32, u32, u32, u32)> void WrapV_IUUUU() {
func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
}
template<void func(u32, u32, u32)> void WrapV_UUU() {
func(PARAM(0), PARAM(1), PARAM(2));
}
@ -141,6 +159,11 @@ template<u32 func(u32, u32, u32, u32)> void WrapU_UUUU() {
RETURN(retval);
}
template<int func(int, u32, u32, u32, u32)> void WrapI_IUUUU() {
int retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
RETURN(retval);
}
template<u32 func(u32, u32, u32, u32, u32)> void WrapU_UUUUU() {
u32 retval = func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
RETURN(retval);

View File

@ -119,7 +119,6 @@ void sceKernelExitGame()
else
PanicAlert("Game exited");
Core_Stop();
RETURN(0);
}
void sceKernelExitGameWithStatus()
@ -130,14 +129,12 @@ void sceKernelExitGameWithStatus()
else
PanicAlert("Game exited (with status)");
Core_Stop();
RETURN(0);
}
void sceKernelRegisterExitCallback()
u32 sceKernelRegisterExitCallback(u32 cbId)
{
u32 cbId = PARAM(0);
DEBUG_LOG(HLE,"NOP sceKernelRegisterExitCallback(%i)", cbId);
RETURN(0);
return 0;
}
// TODO: What?
@ -320,15 +317,15 @@ u32 sceKernelReferGlobalProfiler(u32 statusPtr) {
const HLEFunction ThreadManForUser[] =
{
{0x55C20A00,sceKernelCreateEventFlag, "sceKernelCreateEventFlag"},
{0x812346E4,sceKernelClearEventFlag, "sceKernelClearEventFlag"},
{0xEF9E4C70,sceKernelDeleteEventFlag, "sceKernelDeleteEventFlag"},
{0x1fb15a32,sceKernelSetEventFlag, "sceKernelSetEventFlag"},
{0x402FCF22,sceKernelWaitEventFlag, "sceKernelWaitEventFlag"},
{0x328C546A,sceKernelWaitEventFlagCB, "sceKernelWaitEventFlagCB"},
{0x30FD48F0,sceKernelPollEventFlag, "sceKernelPollEventFlag"},
{0xCD203292,sceKernelCancelEventFlag, "sceKernelCancelEventFlag"},
{0xA66B0120,sceKernelReferEventFlagStatus,"sceKernelReferEventFlagStatus"},
{0x55C20A00,&WrapI_CUUU<sceKernelCreateEventFlag>, "sceKernelCreateEventFlag"},
{0x812346E4,&WrapU_IU<sceKernelClearEventFlag>, "sceKernelClearEventFlag"},
{0xEF9E4C70,&WrapU_I<sceKernelDeleteEventFlag>, "sceKernelDeleteEventFlag"},
{0x1fb15a32,&WrapU_IU<sceKernelSetEventFlag>, "sceKernelSetEventFlag"},
{0x402FCF22,&WrapV_IUUUU<sceKernelWaitEventFlag>, "sceKernelWaitEventFlag"},
{0x328C546A,&WrapV_IUUUU<sceKernelWaitEventFlagCB>, "sceKernelWaitEventFlagCB"},
{0x30FD48F0,&WrapI_IUUUU<sceKernelPollEventFlag>, "sceKernelPollEventFlag"},
{0xCD203292,&WrapU_V<sceKernelCancelEventFlag>, "sceKernelCancelEventFlag"},
{0xA66B0120,&WrapU_IU<sceKernelReferEventFlagStatus>, "sceKernelReferEventFlagStatus"},
{0x8FFDF9A2,&WrapI_IIU<sceKernelCancelSema>, "sceKernelCancelSema"},
{0xD6DA4BA1,sceKernelCreateSema, "sceKernelCreateSema"},
@ -489,10 +486,10 @@ void Register_ThreadManForUser()
const HLEFunction LoadExecForUser[] =
{
{0x05572A5F,sceKernelExitGame, "sceKernelExitGame"}, //()
{0x4AC57943,sceKernelRegisterExitCallback,"sceKernelRegisterExitCallback"},
{0xBD2F1094,sceKernelLoadExec,"sceKernelLoadExec"},
{0x2AC9954B,sceKernelExitGameWithStatus,"sceKernelExitGameWithStatus"},
{0x05572A5F,&WrapV_V<sceKernelExitGame>, "sceKernelExitGame"}, //()
{0x4AC57943,&WrapU_U<sceKernelRegisterExitCallback>,"sceKernelRegisterExitCallback"},
{0xBD2F1094,&WrapI_CU<sceKernelLoadExec>,"sceKernelLoadExec"},
{0x2AC9954B,&WrapV_V<sceKernelExitGameWithStatus>,"sceKernelExitGameWithStatus"},
};
void Register_LoadExecForUser()

View File

@ -244,7 +244,7 @@ bool __KernelIsRunning();
bool __KernelLoadExec(const char *filename, SceKernelLoadExecParam *param);
void sceKernelLoadExec();
int sceKernelLoadExec(const char *filename, u32 paramPtr);
void sceKernelRegisterExitCallback();
void sceKernelExitGame();

View File

@ -87,30 +87,24 @@ enum PspEventFlagWaitTypes
};
//SceUID sceKernelCreateEventFlag(const char *name, int attr, int bits, SceKernelEventFlagOptParam *opt);
void sceKernelCreateEventFlag()
int sceKernelCreateEventFlag(const char *name, u32 flag_attr, u32 flag_initPattern, u32 optPtr)
{
const char *name = Memory::GetCharPointer(PARAM(0));
EventFlag *e = new EventFlag();
SceUID id = kernelObjects.Create(e);
e->nef.size = sizeof(NativeEventFlag);
strncpy(e->nef.name, name, 32);
e->nef.attr = PARAM(1);
e->nef.initPattern = PARAM(2);
e->nef.attr = flag_attr;
e->nef.initPattern = flag_initPattern;
e->nef.currentPattern = e->nef.initPattern;
e->nef.numWaitThreads = 0;
DEBUG_LOG(HLE,"%i=sceKernelCreateEventFlag(\"%s\", %08x, %08x, %08x)", id, e->nef.name, e->nef.attr, e->nef.currentPattern, PARAM(3));
RETURN(id);
DEBUG_LOG(HLE,"%i=sceKernelCreateEventFlag(\"%s\", %08x, %08x, %08x)", id, e->nef.name, e->nef.attr, e->nef.currentPattern, optPtr);
return id;
}
//int sceKernelClearEventFlag(SceUID evid, u32 bits);
void sceKernelClearEventFlag()
u32 sceKernelClearEventFlag(SceUID id, u32 bits)
{
SceUID id = PARAM(0);
u32 bits = PARAM(1);
u32 error;
EventFlag *e = kernelObjects.Get<EventFlag>(id, error);
if (e)
@ -118,21 +112,19 @@ void sceKernelClearEventFlag()
DEBUG_LOG(HLE,"sceKernelClearEventFlag(%i, %08x)", id, bits);
e->nef.currentPattern &= bits;
// Note that it's not possible for threads to get woken up by this action.
RETURN(0);
return 0;
}
else
{
ERROR_LOG(HLE,"sceKernelClearEventFlag(%i, %08x) - error", id, bits);
RETURN(error);
return error;
}
}
//int sceKernelDeleteEventFlag(int evid);
void sceKernelDeleteEventFlag()
u32 sceKernelDeleteEventFlag(SceUID uid)
{
SceUID uid = PARAM(0);
DEBUG_LOG(HLE,"sceKernelDeleteEventFlag(%i)", uid);
RETURN(kernelObjects.Destroy<EventFlag>(uid));
return kernelObjects.Destroy<EventFlag>(uid);
}
u8 __KernelEventFlagMatches(u32 *pattern, u32 bits, u8 wait, u32 outAddr)
@ -151,11 +143,8 @@ u8 __KernelEventFlagMatches(u32 *pattern, u32 bits, u8 wait, u32 outAddr)
return 0;
}
//int sceKernelSetEventFlag(SceUID evid, u32 bits);
void sceKernelSetEventFlag()
u32 sceKernelSetEventFlag(SceUID id, u32 bitsToSet)
{
SceUID id = PARAM(0);
u32 bitsToSet = PARAM(1);
u32 error;
DEBUG_LOG(HLE,"sceKernelSetEventFlag(%i, %08x)", id, bitsToSet);
EventFlag *e = kernelObjects.Get<EventFlag>(id, error);
@ -178,23 +167,17 @@ retry:
goto retry;
}
}
RETURN(0);
return 0;
}
else
{
RETURN(error);
return error;
}
}
//int sceKernelWaitEventFlag(SceUID evid, u32 bits, u32 wait, u32 *outBits, SceUInt *timeout);
void sceKernelWaitEventFlag()
// Actually RETURNs a u32
void sceKernelWaitEventFlag(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32 timeoutPtr)
{
SceUID id = PARAM(0);
u32 bits = PARAM(1);
u32 wait = PARAM(2);
u32 outBitsPtr = PARAM(3);
u32 timeoutPtr = PARAM(4);
DEBUG_LOG(HLE,"sceKernelWaitEventFlag(%i, %08x, %i, %08x, %08x)", id, bits, wait, outBitsPtr, timeoutPtr);
u32 error;
@ -215,8 +198,8 @@ void sceKernelWaitEventFlag()
if (Memory::IsValidAddress(timeoutPtr))
timeout = Memory::Read_U32(timeoutPtr);
__KernelWaitCurThread(WAITTYPE_EVENTFLAG, id, 0, 0, false);
// MUST NOT return a value after __KernelWaitCurThread as we may have been rescheduled!
__KernelWaitCurThread(WAITTYPE_EVENTFLAG, id, 0, 0, false); // sets RETURN
// Do not set RETURN here; it's already set for us and we'd overwrite the wrong thread's RETURN
}
}
else
@ -225,15 +208,9 @@ void sceKernelWaitEventFlag()
}
}
//int sceKernelWaitEventFlagCB(SceUID evid, u32 bits, u32 wait, u32 *outBits, SceUInt *timeout);
void sceKernelWaitEventFlagCB()
// Actually RETURNs a u32
void sceKernelWaitEventFlagCB(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32 timeoutPtr)
{
SceUID id = PARAM(0);
u32 bits = PARAM(1);
u32 wait = PARAM(2);
u32 outBitsPtr = PARAM(3);
u32 timeoutPtr = PARAM(4);
DEBUG_LOG(HLE,"sceKernelWaitEventFlagCB(%i, %08x, %i, %08x, %08x)", id, bits, wait, outBitsPtr, timeoutPtr);
u32 error;
@ -254,7 +231,7 @@ void sceKernelWaitEventFlagCB()
if (Memory::IsValidAddress(timeoutPtr))
timeout = Memory::Read_U32(timeoutPtr);
__KernelWaitCurThread(WAITTYPE_EVENTFLAG, id, 0, 0, true);
__KernelWaitCurThread(WAITTYPE_EVENTFLAG, id, 0, 0, true); // sets RETURN
__KernelCheckCallbacks();
}
}
@ -264,15 +241,8 @@ void sceKernelWaitEventFlagCB()
}
}
//int sceKernelPollEventFlag(int evid, u32 bits, u32 wait, u32 *outBits);
void sceKernelPollEventFlag()
int sceKernelPollEventFlag(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32 timeoutPtr)
{
SceUID id = PARAM(0);
u32 bits = PARAM(1);
u32 wait = PARAM(2);
u32 outBitsPtr = PARAM(3);
u32 timeoutPtr = PARAM(4);
DEBUG_LOG(HLE,"sceKernelPollEventFlag(%i, %08x, %i, %08x, %08x)", id, bits, wait, outBitsPtr, timeoutPtr);
u32 error;
@ -284,42 +254,39 @@ void sceKernelPollEventFlag()
if (Memory::IsValidAddress(outBitsPtr))
Memory::Write_U32(e->nef.currentPattern, outBitsPtr);
// No match - return that, this is polling, not waiting.
RETURN(SCE_KERNEL_ERROR_EVF_COND);
return SCE_KERNEL_ERROR_EVF_COND;
}
else
{
RETURN(0);
return 0;
}
}
else
{
RETURN(error);
return error;
}
}
//int sceKernelReferEventFlagStatus(SceUID event, SceKernelEventFlagInfo *status);
void sceKernelReferEventFlagStatus()
u32 sceKernelReferEventFlagStatus(SceUID id, u32 statusPtr)
{
SceUID id = PARAM(0);
u32 statusAddr = PARAM(1);
DEBUG_LOG(HLE,"sceKernelReferEventFlagStatus(%i, %08x)", id, statusAddr);
DEBUG_LOG(HLE,"sceKernelReferEventFlagStatus(%i, %08x)", id, statusPtr);
u32 error;
EventFlag *e = kernelObjects.Get<EventFlag>(id, error);
if (e)
{
Memory::WriteStruct(statusAddr, &e->nef);
RETURN(0);
Memory::WriteStruct(statusPtr, &e->nef);
return 0;
}
else
{
RETURN(error);
return error;
}
}
// never seen this one
void sceKernelCancelEventFlag()
u32 sceKernelCancelEventFlag()
{
ERROR_LOG(HLE,"UNIMPL: sceKernelCancelEventFlag()");
RETURN(0);
return 0;
}

View File

@ -17,12 +17,12 @@
#pragma once
void sceKernelCreateEventFlag();
void sceKernelClearEventFlag();
void sceKernelDeleteEventFlag();
void sceKernelSetEventFlag();
void sceKernelWaitEventFlag();
void sceKernelWaitEventFlagCB();
void sceKernelPollEventFlag();
void sceKernelCancelEventFlag();
void sceKernelReferEventFlagStatus();
int sceKernelCreateEventFlag(const char *name, u32 flag_attr, u32 flag_initPattern, u32 optPtr);
u32 sceKernelClearEventFlag(SceUID id, u32 bits);
u32 sceKernelDeleteEventFlag(SceUID uid);
u32 sceKernelSetEventFlag(SceUID id, u32 bitsToSet);
void sceKernelWaitEventFlag(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32 timeoutPtr);
void sceKernelWaitEventFlagCB(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32 timeoutPtr);
int sceKernelPollEventFlag(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32 timeoutPtr);
u32 sceKernelReferEventFlagStatus(SceUID id, u32 statusPtr);
u32 sceKernelCancelEventFlag();

View File

@ -519,36 +519,35 @@ bool __KernelLoadExec(const char *filename, SceKernelLoadExecParam *param, std::
}
//TODO: second param
void sceKernelLoadExec()
int sceKernelLoadExec(const char *filename, u32 paramPtr)
{
const char *filename = Memory::GetCharPointer(PARAM(0));
SceKernelLoadExecParam *param = 0;
if (PARAM(1))
if (paramPtr)
{
param = (SceKernelLoadExecParam*)Memory::GetPointer(PARAM(1));
param = (SceKernelLoadExecParam*)Memory::GetPointer(paramPtr);
}
PSPFileInfo info = pspFileSystem.GetFileInfo(filename);
if (!info.exists) {
ERROR_LOG(LOADER, "sceKernelLoadExec(%s, ...): File does not exist", filename);
RETURN(SCE_KERNEL_ERROR_NOFILE);
return;
return SCE_KERNEL_ERROR_NOFILE;
}
s64 size = (s64)info.size;
if (!size)
{
ERROR_LOG(LOADER, "sceKernelLoadExec(%s, ...): File is size 0", filename);
RETURN(SCE_KERNEL_ERROR_ILLEGAL_OBJECT);
return;
return SCE_KERNEL_ERROR_ILLEGAL_OBJECT;
}
DEBUG_LOG(HLE,"sceKernelLoadExec(name=%s,...)", filename);
std::string error_string;
if (!__KernelLoadExec(filename, param, &error_string)) {
ERROR_LOG(HLE, "sceKernelLoadExec failed: %s", error_string.c_str());
return -1;
}
return 0;
}
u32 sceKernelLoadModule(const char *name, u32 flags)

View File

@ -889,10 +889,24 @@ u32 sceKernelStartThread()
void sceKernelGetThreadStackFreeSize()
{
SceUID threadID = PARAM(0);
INFO_LOG(HLE,"sceKernelGetThreadStackFreeSize(%i)", threadID);
u32 error;
Thread *thread = kernelObjects.Get<Thread>(threadID, error);
SceUID threadID = PARAM(0);
Thread *thread;
INFO_LOG(HLE,"sceKernelGetThreadStackFreeSize(%i)", threadID);
if (threadID == 0)
thread = currentThread;
else
{
u32 error;
thread = kernelObjects.Get<Thread>(threadID, error);
if (thread == 0)
{
ERROR_LOG(HLE,"sceKernelGetThreadStackFreeSize: invalid thread id %i", threadID);
RETURN(error);
return;
}
}
// Scan the stack for 0xFF
int sz = 0;

25
test.py
View File

@ -9,6 +9,7 @@ import subprocess
PPSSPP_EXECUTABLES = [ "Windows\\Release\\PPSSPPHeadless.exe", "SDL/build/ppsspp-headless" ]
PPSSPP_EXE = None
TEST_ROOT = "pspautotests/tests/"
teamcity_mode = False
# Test names are the C files without the .c extension.
# These have worked and should keep working always - regression tests.
@ -34,10 +35,8 @@ tests_good = [
"rtc/rtc",
"umd/callbacks/umd",
"power/power",
]
# These are the next tests up for fixing.
tests_next = [
"audio/atrac/atractest",
"audio/sascore/sascore",
"ctrl/ctrl",
@ -68,6 +67,9 @@ tests_next = [
"video/pmf_simple",
]
tests_next = [
]
# These don't even run (or run correctly) on the real PSP
test_broken = [
"sysmem/sysmem",
@ -104,7 +106,10 @@ def init():
print "PPSSPP executable missing, please build one."
sys.exit(1)
def tcprint(arg):
global teamcity_mode
if teamcity_mode:
print arg
def run_tests(test_list, args):
global PPSSPP_EXE
@ -125,14 +130,18 @@ def run_tests(test_list, args):
if not os.path.exists(elf_filename):
print("ERROR: PRX/ELF file missing, failing test: " + test)
tests_failed.append(test)
tcprint("##teamcity[testIgnored name='%s' message='PRX/ELF missing']" % test)
continue
if not os.path.exists(expected_filename):
print("WARNING: expects file missing, failing test: " + test)
tests_failed.append(test)
tcprint("##teamcity[testIgnored name='%s' message='Expects file missing']" % test)
continue
expected_output = open(expected_filename).read()
tcprint("##teamcity[testStarted name='%s' captureStandardOutput='true']" % test)
cmdline = PPSSPP_EXE + " " + elf_filename + " " + " ".join(args)
#print "Cmdline: " + cmdline
@ -142,6 +151,8 @@ def run_tests(test_list, args):
if output.startswith("TESTERROR"):
print "Failed to run test " + elf_filename + "!"
tests_failed.append(test)
tcprint("##teamcity[testFailed name='%s' message='Failed to run test']" % test)
tcprint("##teamcity[testFinished name='%s']" % test)
continue
different = False
@ -165,6 +176,7 @@ def run_tests(test_list, args):
print "+++++++++++++++++++++++++++++++++++++++++++++"
print " " + test + " - passed!"
tests_passed.append(test)
tcprint("##teamcity[testFinished name='%s']" % test)
else:
if '-v' in args:
print "============== output from failed " + test + " :"
@ -173,6 +185,8 @@ def run_tests(test_list, args):
print expected_output
print "==============================="
tests_failed.append(test)
tcprint("##teamcity[testFailed name='%s' message='Output different from expected file']" % test)
tcprint("##teamcity[testFinished name='%s']" % test)
print "%i tests passed, %i tests failed." % (
len(tests_passed), len(tests_failed))
@ -185,11 +199,14 @@ def run_tests(test_list, args):
def main():
global teamcity_mode
init()
tests = []
args = []
for arg in sys.argv[1:]:
if arg[0] == '-':
if arg == '--teamcity':
teamcity_mode = True
elif arg[0] == '-':
args.append(arg)
else:
tests.append(arg)