Merge pull request #233 from unknownbrackets/ctrl-fixes

Implement sceCtrlSetSamplingCycle()
This commit is contained in:
Henrik Rydgård
2012-12-23 00:29:32 -08:00
3 changed files with 83 additions and 24 deletions

View File

@@ -33,6 +33,7 @@
const int PSP_CTRL_ERROR_INVALID_MODE = 0x80000107;
const int PSP_CTRL_ERROR_INVALID_NUM_BUFFERS = 0x80000104;
const int PSP_CTRL_ERROR_INVALID_IDLE_PTR = 0x80000023;
const int NUM_CTRL_BUFFERS = 64;
@@ -72,9 +73,16 @@ static int ctrlBuf = 0;
static int ctrlBufRead = 0;
static CtrlLatch latch;
static int ctrlIdleReset = -1;
static int ctrlIdleBack = -1;
static int ctrlCycle = 0;
static std::vector<SceUID> waitingThreads;
static std::recursive_mutex ctrlMutex;
static int ctrlTimer = -1;
// STATE END
//////////////////////////////////////////////////////////////////////////
@@ -202,9 +210,9 @@ int __CtrlReadBuffer(u32 ctrlDataPtr, u32 nBufs, bool negative, bool peek)
return done;
}
void __CtrlVblank()
void __CtrlDoSample()
{
// When in vblank sampling mode, this samples the ctrl data into the buffers and updates the latch.
// This samples the ctrl data into the buffers and updates the latch.
__CtrlUpdateLatch();
// Wake up a single thread that was waiting for the buffer.
@@ -226,6 +234,22 @@ retry:
}
}
void __CtrlVblank()
{
// This always runs, so make sure we're in vblank mode.
if (ctrlCycle == 0)
__CtrlDoSample();
}
void __CtrlTimerUpdate(u64 userdata, int cyclesLate)
{
// This only runs in timer mode (ctrlCycle > 0.)
_dbg_assert_msg_(HLE, ctrlCycle > 0, "Ctrl: sampling cycle should be > 0");
__CtrlDoSample();
CoreTiming::ScheduleEvent(usToCycles(ctrlCycle), ctrlTimer, 0);
}
void __CtrlInit()
{
std::lock_guard<std::recursive_mutex> guard(ctrlMutex);
@@ -251,33 +275,42 @@ void __CtrlInit()
for (int i = 0; i < NUM_CTRL_BUFFERS; i++)
memcpy(&ctrlBufs[i], &ctrlCurrent, sizeof(_ctrl_data));
}
void sceCtrlInit()
{
__CtrlInit();
ctrlIdleReset = -1;
ctrlIdleBack = -1;
ctrlCycle = 0;
DEBUG_LOG(HLE,"sceCtrlInit");
RETURN(0);
waitingThreads.clear();
ctrlTimer = CoreTiming::RegisterEvent("CtrlSampleTimer", __CtrlTimerUpdate);
}
u32 sceCtrlSetSamplingCycle(u32 cycle)
{
if (cycle == 0)
DEBUG_LOG(HLE, "sceCtrlSetSamplingCycle(%u)", cycle);
if ((cycle > 0 && cycle < 5555) || cycle > 20000)
{
// TODO: Change to vblank when we support something else.
DEBUG_LOG(HLE, "sceCtrlSetSamplingCycle(%u)", cycle);
WARN_LOG(HLE, "SCE_KERNEL_ERROR_INVALID_VALUE=sceCtrlSetSamplingCycle(%u)", cycle);
return SCE_KERNEL_ERROR_INVALID_VALUE;
}
else
{
ERROR_LOG(HLE, "UNIMPL sceCtrlSetSamplingCycle(%u)", cycle);
}
return 0;
u32 prev = ctrlCycle;
ctrlCycle = cycle;
if (prev > 0)
CoreTiming::UnscheduleEvent(ctrlTimer, 0);
if (cycle > 0)
CoreTiming::ScheduleEvent(usToCycles(ctrlCycle), ctrlTimer, 0);
return prev;
}
int sceCtrlGetSamplingCycle(u32 cyclePtr)
{
ERROR_LOG(HLE, "UNIMPL sceCtrlSetSamplingCycle(%08x)", cyclePtr);
DEBUG_LOG(HLE, "sceCtrlSetSamplingCycle(%08x)", cyclePtr);
if (Memory::IsValidAddress(cyclePtr))
Memory::Write_U32(ctrlCycle, cyclePtr);
return 0;
}
@@ -297,6 +330,7 @@ u32 sceCtrlSetSamplingMode(u32 mode)
int sceCtrlGetSamplingMode(u32 modePtr)
{
u32 retVal = analogEnabled == true ? CTRL_MODE_ANALOG : CTRL_MODE_DIGITAL;
DEBUG_LOG(HLE, "%d=sceCtrlGetSamplingMode(%i)", retVal);
if (Memory::IsValidAddress(modePtr))
Memory::Write_U32(retVal, modePtr);
@@ -304,10 +338,33 @@ int sceCtrlGetSamplingMode(u32 modePtr)
return 0;
}
void sceCtrlSetIdleCancelThreshold()
int sceCtrlSetIdleCancelThreshold(int idleReset, int idleBack)
{
ERROR_LOG(HLE,"UNIMPL sceCtrlSetIdleCancelThreshold");
RETURN(0);
DEBUG_LOG(HLE, "FAKE sceCtrlSetIdleCancelThreshold(%d, %d)", idleReset, idleBack);
if (idleReset < -1 || idleBack < -1 || idleReset > 128 || idleBack > 128)
return SCE_KERNEL_ERROR_INVALID_VALUE;
ctrlIdleReset = idleReset;
ctrlIdleBack = idleBack;
return 0;
}
int sceCtrlGetIdleCancelThreshold(u32 idleResetPtr, u32 idleBackPtr)
{
DEBUG_LOG(HLE, "sceCtrlSetIdleCancelThreshold(%08x, %08x)", idleResetPtr, idleBackPtr);
if (idleResetPtr && !Memory::IsValidAddress(idleResetPtr))
return PSP_CTRL_ERROR_INVALID_IDLE_PTR;
if (idleBackPtr && !Memory::IsValidAddress(idleBackPtr))
return PSP_CTRL_ERROR_INVALID_IDLE_PTR;
if (idleResetPtr)
Memory::Write_U32(ctrlIdleReset, idleResetPtr);
if (idleBackPtr)
Memory::Write_U32(ctrlIdleBack, idleBackPtr);
return 0;
}
void sceCtrlReadBufferPositive(u32 ctrlDataPtr, u32 nBufs)
@@ -378,7 +435,7 @@ u32 sceCtrlReadLatch(u32 latchDataPtr)
static const HLEFunction sceCtrl[] =
{
{0x3E65A0EA, WrapV_V<sceCtrlInit>, "sceCtrlInit"}, //(int unknown), init with 0
{0x3E65A0EA, 0, "sceCtrlInit"}, //(int unknown), init with 0
{0x1f4011e6, WrapU_U<sceCtrlSetSamplingMode>, "sceCtrlSetSamplingMode"}, //(int on);
{0x6A2774F3, WrapU_U<sceCtrlSetSamplingCycle>, "sceCtrlSetSamplingCycle"},
{0x02BAAD91, WrapI_U<sceCtrlGetSamplingCycle>,"sceCtrlGetSamplingCycle"},
@@ -393,8 +450,8 @@ static const HLEFunction sceCtrl[] =
{0xAF5960F3, 0, "sceCtrl_AF5960F3"},
{0xA68FD260, 0, "sceCtrlClearRapidFire"},
{0x6841BE1A, 0, "sceCtrlSetRapidFire"},
{0xa7144800, WrapV_V<sceCtrlSetIdleCancelThreshold>, "sceCtrlSetIdleCancelThreshold"},
{0x687660fa, 0, "sceCtrlGetIdleCancelThreshold"},
{0xa7144800, WrapI_II<sceCtrlSetIdleCancelThreshold>, "sceCtrlSetIdleCancelThreshold"},
{0x687660fa, WrapI_UU<sceCtrlGetIdleCancelThreshold>, "sceCtrlGetIdleCancelThreshold"},
};
void Register_sceCtrl()

View File

@@ -49,7 +49,9 @@ tests_good = [
"cpu/fpu/fpu",
"ctrl/ctrl",
"ctrl/idle/idle",
"ctrl/sampling/sampling",
"ctrl/sampling2/sampling2",
"display/display",
"dmac/dmactest",
"loader/bss/bss",