Initiale hbmenu.nro support (#32)
* Initiale hbmenu.nro support Implement missing SetScreenShotPermission object. Implement missing IsCurrentProcessBeingDebugged in SVC. Add a Extension variable to Executable. Add basic support of hbmenu.nro. * Homebrew.cs correction
This commit is contained in:
parent
b2f733da78
commit
224211367f
@ -13,6 +13,7 @@ namespace Ryujinx.Core.Loaders
|
||||
|
||||
public long ImageBase { get; private set; }
|
||||
public long ImageEnd { get; private set; }
|
||||
public Extensions Extension { get; private set; }
|
||||
|
||||
public Executable(IExecutable Exe, AMemory Memory, long ImageBase)
|
||||
{
|
||||
@ -46,6 +47,8 @@ namespace Ryujinx.Core.Loaders
|
||||
long EhHdrEndOffset = Memory.ReadInt32(Mod0Offset + 0x14) + Mod0Offset;
|
||||
long ModObjOffset = Memory.ReadInt32(Mod0Offset + 0x18) + Mod0Offset;
|
||||
|
||||
Extension = Exe.Extension;
|
||||
|
||||
MapBss(BssStartOffset, BssEndOffset - BssStartOffset);
|
||||
|
||||
ImageEnd = BssEndOffset;
|
||||
|
@ -2,6 +2,12 @@ using System.Collections.ObjectModel;
|
||||
|
||||
namespace Ryujinx.Core.Loaders.Executables
|
||||
{
|
||||
public enum Extensions
|
||||
{
|
||||
NRO,
|
||||
NSO
|
||||
}
|
||||
|
||||
public interface IExecutable
|
||||
{
|
||||
ReadOnlyCollection<byte> Text { get; }
|
||||
@ -13,5 +19,7 @@ namespace Ryujinx.Core.Loaders.Executables
|
||||
int ROOffset { get; }
|
||||
int DataOffset { get; }
|
||||
int BssSize { get; }
|
||||
|
||||
Extensions Extension { get; }
|
||||
}
|
||||
}
|
@ -20,6 +20,8 @@ namespace Ryujinx.Core.Loaders.Executables
|
||||
public int DataOffset { get; private set; }
|
||||
public int BssSize { get; private set; }
|
||||
|
||||
public Extensions Extension { get; private set; }
|
||||
|
||||
public Nro(Stream Input)
|
||||
{
|
||||
BinaryReader Reader = new BinaryReader(Input);
|
||||
@ -47,6 +49,8 @@ namespace Ryujinx.Core.Loaders.Executables
|
||||
this.DataOffset = DataOffset;
|
||||
this.BssSize = BssSize;
|
||||
|
||||
this.Extension = Extensions.NRO;
|
||||
|
||||
byte[] Read(long Position, int Size)
|
||||
{
|
||||
Input.Seek(Position, SeekOrigin.Begin);
|
||||
|
@ -21,6 +21,8 @@ namespace Ryujinx.Core.Loaders.Executables
|
||||
public int DataOffset { get; private set; }
|
||||
public int BssSize { get; private set; }
|
||||
|
||||
public Extensions Extension { get; private set; }
|
||||
|
||||
[Flags]
|
||||
private enum NsoFlags
|
||||
{
|
||||
@ -79,6 +81,8 @@ namespace Ryujinx.Core.Loaders.Executables
|
||||
this.DataOffset = DataMemOffset;
|
||||
this.BssSize = BssSize;
|
||||
|
||||
this.Extension = Extensions.NSO;
|
||||
|
||||
//Text segment
|
||||
Input.Seek(TextOffset, SeekOrigin.Begin);
|
||||
|
||||
|
34
Ryujinx.Core/OsHle/Homebrew.cs
Normal file
34
Ryujinx.Core/OsHle/Homebrew.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using ChocolArm64.Memory;
|
||||
|
||||
namespace Ryujinx.Core.OsHle
|
||||
{
|
||||
public class Homebrew
|
||||
{
|
||||
//http://switchbrew.org/index.php?title=Homebrew_ABI
|
||||
public Homebrew(AMemory Memory, long Position, long MainThreadHandle)
|
||||
{
|
||||
//(NbrKeys * LoaderConfigEntrySize) + 2 buffers for Key2
|
||||
long Size = (4 * 0x18) + 0x1000;
|
||||
Memory.Manager.MapPhys(Position, Size, (int)MemoryType.Normal, AMemoryPerm.RW);
|
||||
|
||||
//MainThreadHandle
|
||||
WriteConfigEntry(Memory, ref Position, 1, 0, MainThreadHandle);
|
||||
//NextLoadPath
|
||||
WriteConfigEntry(Memory, ref Position, 2, 0, Position + Size, Position + Size + 0x200);
|
||||
//AppletType
|
||||
WriteConfigEntry(Memory, ref Position, 7);
|
||||
//EndOfList
|
||||
WriteConfigEntry(Memory, ref Position, 0);
|
||||
}
|
||||
|
||||
private void WriteConfigEntry(AMemory Memory, ref long Position, int Key, int Flags = 0, long Value0 = 0L, long Value1 = 0L)
|
||||
{
|
||||
Memory.WriteInt32(Position + 0x00, Key);
|
||||
Memory.WriteInt32(Position + 0x04, Flags);
|
||||
Memory.WriteInt64(Position + 0x08, Value0);
|
||||
Memory.WriteInt64(Position + 0x10, Value1);
|
||||
|
||||
Position += 0x18;
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ namespace Ryujinx.Core.OsHle.Objects.Am
|
||||
{
|
||||
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
||||
{
|
||||
{ 10, SetScreenShotPermission },
|
||||
{ 11, SetOperationModeChangedNotification },
|
||||
{ 12, SetPerformanceModeChangedNotification },
|
||||
{ 13, SetFocusHandlingMode },
|
||||
@ -20,6 +21,13 @@ namespace Ryujinx.Core.OsHle.Objects.Am
|
||||
};
|
||||
}
|
||||
|
||||
public long SetScreenShotPermission(ServiceCtx Context)
|
||||
{
|
||||
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long SetOperationModeChangedNotification(ServiceCtx Context)
|
||||
{
|
||||
bool Enable = Context.RequestData.ReadByte() != 0 ? true : false;
|
||||
|
@ -186,6 +186,13 @@ namespace Ryujinx.Core.OsHle
|
||||
Thread.ThreadState.X1 = (ulong)Handle;
|
||||
Thread.ThreadState.X31 = (ulong)StackTop;
|
||||
|
||||
if (Executables[0].Extension == Extensions.NRO)
|
||||
{
|
||||
Homebrew Homebrew_ABI = new Homebrew(Memory, Executables[0].ImageEnd, (long)Handle);
|
||||
Thread.ThreadState.X0 = (ulong)Executables[0].ImageEnd;
|
||||
Thread.ThreadState.X1 = 0xFFFFFFFFFFFFFFFF;
|
||||
}
|
||||
|
||||
Thread.WorkFinished += ThreadFinished;
|
||||
|
||||
ThreadsByTpidr.TryAdd(Thread.ThreadState.Tpidr, ThreadHnd);
|
||||
|
@ -161,17 +161,18 @@ namespace Ryujinx.Core.OsHle.Svc
|
||||
|
||||
switch (InfoType)
|
||||
{
|
||||
case 2: ThreadState.X1 = GetMapRegionBaseAddr(); break;
|
||||
case 3: ThreadState.X1 = GetMapRegionSize(); break;
|
||||
case 4: ThreadState.X1 = GetHeapRegionBaseAddr(); break;
|
||||
case 5: ThreadState.X1 = GetHeapRegionSize(); break;
|
||||
case 6: ThreadState.X1 = GetTotalMem(); break;
|
||||
case 7: ThreadState.X1 = GetUsedMem(); break;
|
||||
case 11: ThreadState.X1 = GetRnd64(); break;
|
||||
case 12: ThreadState.X1 = GetAddrSpaceBaseAddr(); break;
|
||||
case 13: ThreadState.X1 = GetAddrSpaceSize(); break;
|
||||
case 14: ThreadState.X1 = GetMapRegionBaseAddr(); break;
|
||||
case 15: ThreadState.X1 = GetMapRegionSize(); break;
|
||||
case 2: ThreadState.X1 = GetMapRegionBaseAddr(); break;
|
||||
case 3: ThreadState.X1 = GetMapRegionSize(); break;
|
||||
case 4: ThreadState.X1 = GetHeapRegionBaseAddr(); break;
|
||||
case 5: ThreadState.X1 = GetHeapRegionSize(); break;
|
||||
case 6: ThreadState.X1 = GetTotalMem(); break;
|
||||
case 7: ThreadState.X1 = GetUsedMem(); break;
|
||||
case 8: ThreadState.X1 = IsCurrentProcessBeingDebugged(); break;
|
||||
case 11: ThreadState.X1 = GetRnd64(); break;
|
||||
case 12: ThreadState.X1 = GetAddrSpaceBaseAddr(); break;
|
||||
case 13: ThreadState.X1 = GetAddrSpaceSize(); break;
|
||||
case 14: ThreadState.X1 = GetMapRegionBaseAddr(); break;
|
||||
case 15: ThreadState.X1 = GetMapRegionSize(); break;
|
||||
|
||||
default: throw new NotImplementedException($"SvcGetInfo: {InfoType} {Handle} {InfoId}");
|
||||
}
|
||||
@ -179,31 +180,6 @@ namespace Ryujinx.Core.OsHle.Svc
|
||||
ThreadState.X0 = (int)SvcResult.Success;
|
||||
}
|
||||
|
||||
private ulong GetTotalMem()
|
||||
{
|
||||
return (ulong)Memory.Manager.GetTotalMemorySize();
|
||||
}
|
||||
|
||||
private ulong GetUsedMem()
|
||||
{
|
||||
return (ulong)Memory.Manager.GetUsedMemorySize();
|
||||
}
|
||||
|
||||
private ulong GetRnd64()
|
||||
{
|
||||
return (ulong)Rng.Next() + ((ulong)Rng.Next() << 32);
|
||||
}
|
||||
|
||||
private ulong GetAddrSpaceBaseAddr()
|
||||
{
|
||||
return 0x08000000;
|
||||
}
|
||||
|
||||
private ulong GetAddrSpaceSize()
|
||||
{
|
||||
return AMemoryMgr.AddrSize - GetAddrSpaceBaseAddr();
|
||||
}
|
||||
|
||||
private ulong GetMapRegionBaseAddr()
|
||||
{
|
||||
return 0x80000000;
|
||||
@ -223,5 +199,35 @@ namespace Ryujinx.Core.OsHle.Svc
|
||||
{
|
||||
return 0x40000000;
|
||||
}
|
||||
|
||||
private ulong GetTotalMem()
|
||||
{
|
||||
return (ulong)Memory.Manager.GetTotalMemorySize();
|
||||
}
|
||||
|
||||
private ulong GetUsedMem()
|
||||
{
|
||||
return (ulong)Memory.Manager.GetUsedMemorySize();
|
||||
}
|
||||
|
||||
private ulong IsCurrentProcessBeingDebugged()
|
||||
{
|
||||
return (ulong)0;
|
||||
}
|
||||
|
||||
private ulong GetRnd64()
|
||||
{
|
||||
return (ulong)Rng.Next() + ((ulong)Rng.Next() << 32);
|
||||
}
|
||||
|
||||
private ulong GetAddrSpaceBaseAddr()
|
||||
{
|
||||
return 0x08000000;
|
||||
}
|
||||
|
||||
private ulong GetAddrSpaceSize()
|
||||
{
|
||||
return AMemoryMgr.AddrSize - GetAddrSpaceBaseAddr();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user