Esempio n. 1
0
        public virtual void reset()
        {
            status = PSP_THREAD_STOPPED;

            int    k0  = stackAddr + stackSize - 0x100;         // setup k0
            Memory mem = Memory.Instance;

            if (stackAddr != 0 && stackSize > 0 && !preserveStack)
            {
                // set stack to 0xFF
                if ((attr & PSP_THREAD_ATTR_NO_FILLSTACK) != PSP_THREAD_ATTR_NO_FILLSTACK)
                {
                    mem.memset(stackAddr, unchecked ((sbyte)0xFF), stackSize);
                }

                // setup k0
                mem.memset(k0, (sbyte)0x0, 0x100);
                mem.write32(k0 + 0xc0, stackAddr);
                mem.write32(k0 + 0xca, uid);
                mem.write32(k0 + 0xf8, unchecked ((int)0xffffffff));
                mem.write32(k0 + 0xfc, unchecked ((int)0xffffffff));

                mem.write32(stackAddr, uid);
            }

            currentPriority    = initPriority;
            waitType           = PSP_WAIT_NONE;
            waitId             = 0;
            wakeupCount        = 0;
            exitStatus         = ERROR_KERNEL_THREAD_ALREADY_DORMANT;     // Threads start with DORMANT and not NOT_DORMANT (tested and checked).
            exitStatusAddr     = null;
            runClocks          = 0;
            intrPreemptCount   = 0;
            threadPreemptCount = 0;
            releaseCount       = 0;
            notifyCallback     = 0;

            // Thread specific registers
            cpuContext.pc  = entry_addr;
            cpuContext.npc = entry_addr;             // + 4;

            // Reset all the registers to DEADBEEF value
            for (int i = _ra; i > _zr; i--)
            {
                cpuContext.setRegister(i, unchecked ((int)0xDEADBEEF));
            }
            cpuContext._k0 = 0;
            cpuContext._k1 = 0;
            if (UserMode)
            {
                cpuContext._k1 |= 0x100000;
            }
            cpuContext._k1 |= 0x100000;
            int   intNanValue = 0x7F800001;
            float nanValue    = Float.intBitsToFloat(intNanValue);

            for (int i = Common._f31; i >= Common._f0; i--)
            {
                cpuContext.fpr[i] = nanValue;
            }
            cpuContext.hilo = unchecked ((long)0xDEADBEEFDEADBEEFL);

            if ((attr & PSP_THREAD_ATTR_VFPU) != 0)
            {
                // Reset the VFPU context
                for (int m = 0; m < 8; m++)
                {
                    for (int c = 0; c < 4; c++)
                    {
                        for (int r = 0; r < 4; r++)
                        {
                            cpuContext.setVprInt(m, c, r, intNanValue);
                        }
                    }
                }
                for (int i = 0; i < cpuContext.vcr.cc.Length; i++)
                {
                    cpuContext.vcr.cc[i] = true;
                }
                cpuContext.vcr.pfxs.reset();
                cpuContext.vcr.pfxt.reset();
                cpuContext.vcr.pfxd.reset();
            }

            // sp, 512 byte padding at the top for user data, this will get re-jigged when we call start thread
            cpuContext._sp = stackAddr + stackSize - 512;
            cpuContext._k0 = k0;

            // We'll hook "jr $ra" where $ra == address of HLE syscall hleKernelExitThread
            // when the thread is exiting
            cpuContext._ra = pspsharp.HLE.modules.ThreadManForUser.THREAD_EXIT_HANDLER_ADDRESS;

            doDelete    = false;
            doCallbacks = false;

            registeredCallbacks = new RegisteredCallbacks[THREAD_CALLBACK_SIZE];
            for (int i = 0; i < registeredCallbacks.Length; i++)
            {
                registeredCallbacks[i] = new RegisteredCallbacks(i);
            }
            // The UMD callback registers only the last callback.
            registeredCallbacks[THREAD_CALLBACK_UMD].setRegisterOnlyLastCallback();
        }