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); }