public uint sceKernelCreateThread(CpuThreadState CpuThreadState, string Name,
                                          uint /*SceKernelThreadEntry*/ EntryPoint, int InitPriority, int StackSize, PspThreadAttributes Attribute,
                                          SceKernelThreadOptParam *Option)
        {
            // 512 byte min. (required for interrupts)
            StackSize = Math.Max(StackSize, 0x200);
            // Aligned to 256 bytes.
            StackSize = (int)MathUtils.NextAligned(StackSize, 0x100);

            var Thread = ThreadManager.Create();

            Thread.Name = Name;
            Thread.Info.PriorityCurrent   = InitPriority;
            Thread.Info.PriorityInitially = InitPriority;

#if USE_RIGHT_PRIORITY_VALUE
            Thread.PriorityValue = InitPriority;
#endif

            Thread.Attribute       = Attribute;
            Thread.GP              = CpuThreadState.Gp;
            Thread.Info.EntryPoint = (SceKernelThreadEntry)EntryPoint;

            //var ThreadStackPartition = MemoryManager.GetPartition(MemoryPartitions.User);
            //var ThreadStackPartition = MemoryManager.GetPartition(MemoryPartitions.UserStacks);
            var ThreadStackPartition = MemoryManager.GetPartition(MemoryPartitions.Kernel0);

            Thread.Stack = ThreadStackPartition.Allocate(
                StackSize,
                MemoryPartition.Anchor.High,
                Alignment: 0x100,
                Name: "<Stack> : " + Name
                );

            if (!Thread.Attribute.HasFlag(PspThreadAttributes.NoFillStack))
            {
                MemoryManager.Memory.WriteRepeated1(0xFF, Thread.Stack.Low, Thread.Stack.Size - 0x100);
                //Console.Error.WriteLine("-------------------------------------------------");
                //Console.Error.WriteLine("'{0}', '{1}'", StackSize, Thread.Stack.Size);
                //Console.Error.WriteLine("-------------------------------------------------");
            }
            Thread.Info.StackPointer = Thread.Stack.High;
            Thread.Info.StackSize    = StackSize;

            // Used K0 from parent thread.
            // @FAKE. K0 should be preserved between thread calls. Though probably not modified by user modules.
            if (ThreadManager.Current != null)
            {
                Thread.CpuThreadState.CopyRegistersFrom(ThreadManager.Current.CpuThreadState);
            }

            Thread.CpuThreadState.Pc = (uint)EntryPoint;
            Thread.CpuThreadState.Ra = (uint)HleEmulatorSpecialAddresses.CODE_PTR_EXIT_THREAD;
            Thread.SetStatus(HleThread.Status.Stopped);
            //Thread.CpuThreadState.RA = (uint)0;


            uint StackLow = Thread.Stack.Low;
            uint SP       = Thread.Stack.High - 0x200;
            uint K0       = Thread.Stack.High - 0x100;

            CpuThreadState.CpuProcessor.Memory.WriteStruct(StackLow, Thread.Id);
            CpuThreadState.CpuProcessor.Memory.WriteRepeated1(0x00, K0, 0x100);
            CpuThreadState.CpuProcessor.Memory.WriteStruct(K0 + 0xC0, StackLow);
            CpuThreadState.CpuProcessor.Memory.WriteStruct(K0 + 0xCA, Thread.Id);
            CpuThreadState.CpuProcessor.Memory.WriteStruct(K0 + 0xF8, 0xFFFFFFFF);
            CpuThreadState.CpuProcessor.Memory.WriteStruct(K0 + 0xFC, 0xFFFFFFFF);

            Thread.CpuThreadState.Sp = SP;
            //ThreadToStart.CpuThreadState.FP = 0xDEADBEEF;
            Thread.CpuThreadState.K0 = K0;

            //Console.WriteLine("STACK: {0:X}", Thread.CpuThreadState.SP);

            return((uint)Thread.Id);
        }
        public uint sceKernelCreateThread(CpuThreadState CpuThreadState, string Name, uint /*SceKernelThreadEntry*/ EntryPoint, int InitPriority, int StackSize, PspThreadAttributes Attribute, SceKernelThreadOptParam *Option)
        {
            var Thread = HleState.ThreadManager.Create();

            Thread.Name = Name;
            Thread.Info.PriorityCurrent   = InitPriority;
            Thread.Info.PriorityInitially = InitPriority;
            Thread.Attribute       = Attribute;
            Thread.GP              = CpuThreadState.GP;
            Thread.Info.EntryPoint = (SceKernelThreadEntry)EntryPoint;
            Thread.Stack           = HleState.MemoryManager.GetPartition(HleMemoryManager.Partitions.User).Allocate(StackSize, MemoryPartition.Anchor.High, Alignment: 0x100);
            if (!Thread.Attribute.HasFlag(PspThreadAttributes.NoFillStack))
            {
                HleState.MemoryManager.Memory.WriteRepeated1(0xFF, Thread.Stack.Low, Thread.Stack.Size);
                //Console.Error.WriteLine("-------------------------------------------------");
                //Console.Error.WriteLine("'{0}', '{1}'", StackSize, Thread.Stack.Size);
                //Console.Error.WriteLine("-------------------------------------------------");
            }
            Thread.Info.StackPointer = Thread.Stack.High;
            Thread.Info.StackSize    = StackSize;

            // Used K0 from parent thread.
            // @FAKE. K0 should be preserved between thread calls. Though probably not modified by user modules.
            Thread.CpuThreadState.CopyRegistersFrom(HleState.ThreadManager.Current.CpuThreadState);

            Thread.CpuThreadState.PC = (uint)EntryPoint;
            Thread.CpuThreadState.GP = (uint)CpuThreadState.GP;
            Thread.CpuThreadState.SP = (uint)(Thread.Stack.High);
            Thread.CpuThreadState.RA = (uint)HleEmulatorSpecialAddresses.CODE_PTR_EXIT_THREAD;
            Thread.CurrentStatus     = HleThread.Status.Stopped;
            //Thread.CpuThreadState.RA = (uint)0;

            //Console.WriteLine("STACK: {0:X}", Thread.CpuThreadState.SP);

            return((uint)Thread.Id);
        }