forked from Mirror/Ryujinx
Disable memory checks by default, even on debug, move ram memory allocation inside the CPU, since the size if fixed anyway, better heap region size
This commit is contained in:
parent
be0e4007dc
commit
5912bd2beb
12 changed files with 177 additions and 207 deletions
|
@ -1,4 +1,4 @@
|
||||||
public static class AOptimizations
|
public static class AOptimizations
|
||||||
{
|
{
|
||||||
|
public static bool EnableMemoryChecks = false;
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@ namespace ChocolArm64
|
||||||
public AThreadState ThreadState { get; private set; }
|
public AThreadState ThreadState { get; private set; }
|
||||||
public AMemory Memory { get; private set; }
|
public AMemory Memory { get; private set; }
|
||||||
|
|
||||||
public long EntryPoint { get; private set; }
|
private long EntryPoint;
|
||||||
|
|
||||||
private ATranslator Translator;
|
private ATranslator Translator;
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@ using ChocolArm64.State;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace ChocolArm64.Memory
|
namespace ChocolArm64.Memory
|
||||||
{
|
{
|
||||||
public unsafe class AMemory
|
public unsafe class AMemory : IDisposable
|
||||||
{
|
{
|
||||||
private const long ErgMask = (4 << AThreadState.ErgSizeLog2) - 1;
|
private const long ErgMask = (4 << AThreadState.ErgSizeLog2) - 1;
|
||||||
|
|
||||||
|
@ -39,9 +40,11 @@ namespace ChocolArm64.Memory
|
||||||
|
|
||||||
private HashSet<long> ExAddrs;
|
private HashSet<long> ExAddrs;
|
||||||
|
|
||||||
|
public IntPtr Ram { get; private set; }
|
||||||
|
|
||||||
private byte* RamPtr;
|
private byte* RamPtr;
|
||||||
|
|
||||||
public AMemory(IntPtr Ram)
|
public AMemory()
|
||||||
{
|
{
|
||||||
Manager = new AMemoryMgr();
|
Manager = new AMemoryMgr();
|
||||||
|
|
||||||
|
@ -49,6 +52,8 @@ namespace ChocolArm64.Memory
|
||||||
|
|
||||||
ExAddrs = new HashSet<long>();
|
ExAddrs = new HashSet<long>();
|
||||||
|
|
||||||
|
Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize + AMemoryMgr.PageSize);
|
||||||
|
|
||||||
RamPtr = (byte*)Ram;
|
RamPtr = (byte*)Ram;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,9 +147,7 @@ namespace ChocolArm64.Memory
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public byte ReadByte(long Position)
|
public byte ReadByte(long Position)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Read);
|
EnsureAccessIsValid(Position, AMemoryPerm.Read);
|
||||||
#endif
|
|
||||||
|
|
||||||
return *((byte*)(RamPtr + (uint)Position));
|
return *((byte*)(RamPtr + (uint)Position));
|
||||||
}
|
}
|
||||||
|
@ -152,9 +155,8 @@ namespace ChocolArm64.Memory
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ushort ReadUInt16(long Position)
|
public ushort ReadUInt16(long Position)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
EnsureAccessIsValid(Position + 0, AMemoryPerm.Read);
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Read);
|
EnsureAccessIsValid(Position + 1, AMemoryPerm.Read);
|
||||||
#endif
|
|
||||||
|
|
||||||
return *((ushort*)(RamPtr + (uint)Position));
|
return *((ushort*)(RamPtr + (uint)Position));
|
||||||
}
|
}
|
||||||
|
@ -162,9 +164,8 @@ namespace ChocolArm64.Memory
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public uint ReadUInt32(long Position)
|
public uint ReadUInt32(long Position)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
EnsureAccessIsValid(Position + 0, AMemoryPerm.Read);
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Read);
|
EnsureAccessIsValid(Position + 3, AMemoryPerm.Read);
|
||||||
#endif
|
|
||||||
|
|
||||||
return *((uint*)(RamPtr + (uint)Position));
|
return *((uint*)(RamPtr + (uint)Position));
|
||||||
}
|
}
|
||||||
|
@ -172,9 +173,8 @@ namespace ChocolArm64.Memory
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ulong ReadUInt64(long Position)
|
public ulong ReadUInt64(long Position)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
EnsureAccessIsValid(Position + 0, AMemoryPerm.Read);
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Read);
|
EnsureAccessIsValid(Position + 7, AMemoryPerm.Read);
|
||||||
#endif
|
|
||||||
|
|
||||||
return *((ulong*)(RamPtr + (uint)Position));
|
return *((ulong*)(RamPtr + (uint)Position));
|
||||||
}
|
}
|
||||||
|
@ -182,50 +182,30 @@ namespace ChocolArm64.Memory
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public AVec ReadVector8(long Position)
|
public AVec ReadVector8(long Position)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Read);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return new AVec() { B0 = ReadByte(Position) };
|
return new AVec() { B0 = ReadByte(Position) };
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public AVec ReadVector16(long Position)
|
public AVec ReadVector16(long Position)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Read);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return new AVec() { H0 = ReadUInt16(Position) };
|
return new AVec() { H0 = ReadUInt16(Position) };
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public AVec ReadVector32(long Position)
|
public AVec ReadVector32(long Position)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Read);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return new AVec() { W0 = ReadUInt32(Position) };
|
return new AVec() { W0 = ReadUInt32(Position) };
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public AVec ReadVector64(long Position)
|
public AVec ReadVector64(long Position)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Read);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return new AVec() { X0 = ReadUInt64(Position) };
|
return new AVec() { X0 = ReadUInt64(Position) };
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public AVec ReadVector128(long Position)
|
public AVec ReadVector128(long Position)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Read);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return new AVec()
|
return new AVec()
|
||||||
{
|
{
|
||||||
X0 = ReadUInt64(Position + 0),
|
X0 = ReadUInt64(Position + 0),
|
||||||
|
@ -241,9 +221,7 @@ namespace ChocolArm64.Memory
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void WriteByte(long Position, byte Value)
|
public void WriteByte(long Position, byte Value)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Write);
|
EnsureAccessIsValid(Position, AMemoryPerm.Write);
|
||||||
#endif
|
|
||||||
|
|
||||||
*((byte*)(RamPtr + (uint)Position)) = Value;
|
*((byte*)(RamPtr + (uint)Position)) = Value;
|
||||||
}
|
}
|
||||||
|
@ -251,9 +229,8 @@ namespace ChocolArm64.Memory
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void WriteUInt16(long Position, ushort Value)
|
public void WriteUInt16(long Position, ushort Value)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
EnsureAccessIsValid(Position + 0, AMemoryPerm.Write);
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Write);
|
EnsureAccessIsValid(Position + 1, AMemoryPerm.Write);
|
||||||
#endif
|
|
||||||
|
|
||||||
*((ushort*)(RamPtr + (uint)Position)) = Value;
|
*((ushort*)(RamPtr + (uint)Position)) = Value;
|
||||||
}
|
}
|
||||||
|
@ -261,9 +238,8 @@ namespace ChocolArm64.Memory
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void WriteUInt32(long Position, uint Value)
|
public void WriteUInt32(long Position, uint Value)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
EnsureAccessIsValid(Position + 0, AMemoryPerm.Write);
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Write);
|
EnsureAccessIsValid(Position + 3, AMemoryPerm.Write);
|
||||||
#endif
|
|
||||||
|
|
||||||
*((uint*)(RamPtr + (uint)Position)) = Value;
|
*((uint*)(RamPtr + (uint)Position)) = Value;
|
||||||
}
|
}
|
||||||
|
@ -271,9 +247,8 @@ namespace ChocolArm64.Memory
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void WriteUInt64(long Position, ulong Value)
|
public void WriteUInt64(long Position, ulong Value)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
EnsureAccessIsValid(Position + 0, AMemoryPerm.Write);
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Write);
|
EnsureAccessIsValid(Position + 7, AMemoryPerm.Write);
|
||||||
#endif
|
|
||||||
|
|
||||||
*((ulong*)(RamPtr + (uint)Position)) = Value;
|
*((ulong*)(RamPtr + (uint)Position)) = Value;
|
||||||
}
|
}
|
||||||
|
@ -281,64 +256,64 @@ namespace ChocolArm64.Memory
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void WriteVector8(long Position, AVec Value)
|
public void WriteVector8(long Position, AVec Value)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Write);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WriteByte(Position, Value.B0);
|
WriteByte(Position, Value.B0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void WriteVector16(long Position, AVec Value)
|
public void WriteVector16(long Position, AVec Value)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Write);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WriteUInt16(Position, Value.H0);
|
WriteUInt16(Position, Value.H0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void WriteVector32(long Position, AVec Value)
|
public void WriteVector32(long Position, AVec Value)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Write);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WriteUInt32(Position, Value.W0);
|
WriteUInt32(Position, Value.W0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void WriteVector64(long Position, AVec Value)
|
public void WriteVector64(long Position, AVec Value)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Write);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WriteUInt64(Position, Value.X0);
|
WriteUInt64(Position, Value.X0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void WriteVector128(long Position, AVec Value)
|
public void WriteVector128(long Position, AVec Value)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
EnsureAccessIsValid(Position, AMemoryPerm.Write);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WriteUInt64(Position + 0, Value.X0);
|
WriteUInt64(Position + 0, Value.X0);
|
||||||
WriteUInt64(Position + 8, Value.X1);
|
WriteUInt64(Position + 8, Value.X1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnsureAccessIsValid(long Position, AMemoryPerm Perm)
|
private void EnsureAccessIsValid(long Position, AMemoryPerm Perm)
|
||||||
{
|
{
|
||||||
if (!Manager.IsMapped(Position))
|
#if DEBUG
|
||||||
|
if (AOptimizations.EnableMemoryChecks)
|
||||||
{
|
{
|
||||||
throw new VmmPageFaultException(Position);
|
if (!Manager.IsMapped(Position))
|
||||||
}
|
{
|
||||||
|
throw new VmmPageFaultException(Position);
|
||||||
|
}
|
||||||
|
|
||||||
if (!Manager.HasPermission(Position, Perm))
|
if (!Manager.HasPermission(Position, Perm))
|
||||||
|
{
|
||||||
|
throw new VmmAccessViolationException(Position, Perm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (Ram != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
throw new VmmAccessViolationException(Position, Perm);
|
Marshal.FreeHGlobal(Ram);
|
||||||
|
|
||||||
|
Ram = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ namespace ChocolArm64.Memory
|
||||||
{
|
{
|
||||||
public class AMemoryMgr
|
public class AMemoryMgr
|
||||||
{
|
{
|
||||||
public const long AddrSize = RamSize;
|
|
||||||
public const long RamSize = 4L * 1024 * 1024 * 1024;
|
public const long RamSize = 4L * 1024 * 1024 * 1024;
|
||||||
|
public const long AddrSize = RamSize;
|
||||||
|
|
||||||
private const int PTLvl0Bits = 10;
|
private const int PTLvl0Bits = 10;
|
||||||
private const int PTLvl1Bits = 10;
|
private const int PTLvl1Bits = 10;
|
||||||
|
@ -19,8 +19,8 @@ namespace ChocolArm64.Memory
|
||||||
private const int PTLvl1Mask = PTLvl1Size - 1;
|
private const int PTLvl1Mask = PTLvl1Size - 1;
|
||||||
public const int PageMask = PageSize - 1;
|
public const int PageMask = PageSize - 1;
|
||||||
|
|
||||||
private const int PTLvl0Bit = PTPageBits + PTLvl1Bits;
|
private const int PTLvl0Bit = PTPageBits + PTLvl1Bits;
|
||||||
private const int PTLvl1Bit = PTPageBits;
|
private const int PTLvl1Bit = PTPageBits;
|
||||||
|
|
||||||
private enum PTMap
|
private enum PTMap
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using ChocolArm64.Memory;
|
using Ryujinx.Core.OsHle.Handles;
|
||||||
using Ryujinx.Core.OsHle.Handles;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace Ryujinx.Core.Input
|
namespace Ryujinx.Core.Input
|
||||||
{
|
{
|
||||||
|
@ -66,11 +64,15 @@ namespace Ryujinx.Core.Input
|
||||||
|
|
||||||
private long[] ShMemPositions;
|
private long[] ShMemPositions;
|
||||||
|
|
||||||
private IntPtr Ram;
|
private long CurrControllerEntry;
|
||||||
|
private long CurrTouchEntry;
|
||||||
|
private long CurrTouchSampleCounter;
|
||||||
|
|
||||||
public Hid(IntPtr Ram)
|
private Switch Ns;
|
||||||
|
|
||||||
|
public Hid(Switch Ns)
|
||||||
{
|
{
|
||||||
this.Ram = Ram;
|
this.Ns = Ns;
|
||||||
|
|
||||||
ShMemLock = new object();
|
ShMemLock = new object();
|
||||||
|
|
||||||
|
@ -136,20 +138,20 @@ namespace Ryujinx.Core.Input
|
||||||
|
|
||||||
HidControllerColorDesc SplitColorDesc = 0;
|
HidControllerColorDesc SplitColorDesc = 0;
|
||||||
|
|
||||||
WriteInt32(BaseControllerOffset + 0x0, (int)Type);
|
Ns.Memory.WriteInt32(BaseControllerOffset + 0x0, (int)Type);
|
||||||
|
|
||||||
WriteInt32(BaseControllerOffset + 0x4, IsHalf ? 1 : 0);
|
Ns.Memory.WriteInt32(BaseControllerOffset + 0x4, IsHalf ? 1 : 0);
|
||||||
|
|
||||||
WriteInt32(BaseControllerOffset + 0x8, (int)SingleColorDesc);
|
Ns.Memory.WriteInt32(BaseControllerOffset + 0x8, (int)SingleColorDesc);
|
||||||
WriteInt32(BaseControllerOffset + 0xc, (int)SingleColorBody);
|
Ns.Memory.WriteInt32(BaseControllerOffset + 0xc, (int)SingleColorBody);
|
||||||
WriteInt32(BaseControllerOffset + 0x10, (int)SingleColorButtons);
|
Ns.Memory.WriteInt32(BaseControllerOffset + 0x10, (int)SingleColorButtons);
|
||||||
WriteInt32(BaseControllerOffset + 0x14, (int)SplitColorDesc);
|
Ns.Memory.WriteInt32(BaseControllerOffset + 0x14, (int)SplitColorDesc);
|
||||||
|
|
||||||
WriteInt32(BaseControllerOffset + 0x18, (int)LeftColorBody);
|
Ns.Memory.WriteInt32(BaseControllerOffset + 0x18, (int)LeftColorBody);
|
||||||
WriteInt32(BaseControllerOffset + 0x1c, (int)LeftColorButtons);
|
Ns.Memory.WriteInt32(BaseControllerOffset + 0x1c, (int)LeftColorButtons);
|
||||||
|
|
||||||
WriteInt32(BaseControllerOffset + 0x20, (int)RightColorBody);
|
Ns.Memory.WriteInt32(BaseControllerOffset + 0x20, (int)RightColorBody);
|
||||||
WriteInt32(BaseControllerOffset + 0x24, (int)RightColorButtons);
|
Ns.Memory.WriteInt32(BaseControllerOffset + 0x24, (int)RightColorButtons);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetJoyconButton(
|
public void SetJoyconButton(
|
||||||
|
@ -163,119 +165,119 @@ namespace Ryujinx.Core.Input
|
||||||
{
|
{
|
||||||
foreach (long Position in ShMemPositions)
|
foreach (long Position in ShMemPositions)
|
||||||
{
|
{
|
||||||
long ControllerOffset = Position + HidControllersOffset;
|
WriteJoyconButtons(
|
||||||
|
Position,
|
||||||
ControllerOffset += (int)ControllerId * HidControllerSize;
|
ControllerId,
|
||||||
|
ControllerLayout,
|
||||||
ControllerOffset += HidControllerHeaderSize;
|
Buttons,
|
||||||
|
LeftStick,
|
||||||
ControllerOffset += (int)ControllerLayout * HidControllerLayoutsSize;
|
RightStick);
|
||||||
|
|
||||||
long LastEntry = ReadInt64(ControllerOffset + 0x10);
|
|
||||||
|
|
||||||
long CurrEntry = (LastEntry + 1) % HidEntryCount;
|
|
||||||
|
|
||||||
long Timestamp = Stopwatch.GetTimestamp();
|
|
||||||
|
|
||||||
WriteInt64(ControllerOffset + 0x0, Timestamp);
|
|
||||||
WriteInt64(ControllerOffset + 0x8, HidEntryCount);
|
|
||||||
WriteInt64(ControllerOffset + 0x10, CurrEntry);
|
|
||||||
WriteInt64(ControllerOffset + 0x18, HidEntryCount - 1);
|
|
||||||
|
|
||||||
ControllerOffset += HidControllersLayoutHeaderSize;
|
|
||||||
|
|
||||||
ControllerOffset += CurrEntry * HidControllersInputEntrySize;
|
|
||||||
|
|
||||||
WriteInt64(ControllerOffset + 0x0, Timestamp);
|
|
||||||
WriteInt64(ControllerOffset + 0x8, Timestamp);
|
|
||||||
|
|
||||||
WriteInt64(ControllerOffset + 0x10, (uint)Buttons);
|
|
||||||
|
|
||||||
WriteInt32(ControllerOffset + 0x18, LeftStick.DX);
|
|
||||||
WriteInt32(ControllerOffset + 0x1c, LeftStick.DY);
|
|
||||||
|
|
||||||
WriteInt64(ControllerOffset + 0x20, RightStick.DX);
|
|
||||||
WriteInt64(ControllerOffset + 0x24, RightStick.DY);
|
|
||||||
|
|
||||||
WriteInt64(ControllerOffset + 0x28,
|
|
||||||
(uint)HidControllerConnState.Controller_State_Connected |
|
|
||||||
(uint)HidControllerConnState.Controller_State_Wired);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void WriteJoyconButtons(
|
||||||
|
long BasePosition,
|
||||||
|
HidControllerId ControllerId,
|
||||||
|
HidControllerLayouts ControllerLayout,
|
||||||
|
HidControllerButtons Buttons,
|
||||||
|
HidJoystickPosition LeftStick,
|
||||||
|
HidJoystickPosition RightStick)
|
||||||
|
{
|
||||||
|
long ControllerOffset = BasePosition + HidControllersOffset;
|
||||||
|
|
||||||
|
ControllerOffset += (int)ControllerId * HidControllerSize;
|
||||||
|
|
||||||
|
ControllerOffset += HidControllerHeaderSize;
|
||||||
|
|
||||||
|
ControllerOffset += (int)ControllerLayout * HidControllerLayoutsSize;
|
||||||
|
|
||||||
|
CurrControllerEntry = (CurrControllerEntry + 1) % HidEntryCount;
|
||||||
|
|
||||||
|
long Timestamp = GetTimestamp();
|
||||||
|
|
||||||
|
Ns.Memory.WriteInt64(ControllerOffset + 0x0, Timestamp);
|
||||||
|
Ns.Memory.WriteInt64(ControllerOffset + 0x8, HidEntryCount);
|
||||||
|
Ns.Memory.WriteInt64(ControllerOffset + 0x10, CurrControllerEntry);
|
||||||
|
Ns.Memory.WriteInt64(ControllerOffset + 0x18, HidEntryCount - 1);
|
||||||
|
|
||||||
|
ControllerOffset += HidControllersLayoutHeaderSize;
|
||||||
|
|
||||||
|
ControllerOffset += CurrControllerEntry * HidControllersInputEntrySize;
|
||||||
|
|
||||||
|
Ns.Memory.WriteInt64(ControllerOffset + 0x0, Timestamp);
|
||||||
|
Ns.Memory.WriteInt64(ControllerOffset + 0x8, Timestamp);
|
||||||
|
|
||||||
|
Ns.Memory.WriteInt64(ControllerOffset + 0x10, (uint)Buttons);
|
||||||
|
|
||||||
|
Ns.Memory.WriteInt32(ControllerOffset + 0x18, LeftStick.DX);
|
||||||
|
Ns.Memory.WriteInt32(ControllerOffset + 0x1c, LeftStick.DY);
|
||||||
|
|
||||||
|
Ns.Memory.WriteInt32(ControllerOffset + 0x20, RightStick.DX);
|
||||||
|
Ns.Memory.WriteInt32(ControllerOffset + 0x24, RightStick.DY);
|
||||||
|
|
||||||
|
Ns.Memory.WriteInt64(ControllerOffset + 0x28,
|
||||||
|
(uint)HidControllerConnState.Controller_State_Connected |
|
||||||
|
(uint)HidControllerConnState.Controller_State_Wired);
|
||||||
|
}
|
||||||
|
|
||||||
public void SetTouchPoints(params HidTouchPoint[] Points)
|
public void SetTouchPoints(params HidTouchPoint[] Points)
|
||||||
{
|
{
|
||||||
lock (ShMemLock)
|
lock (ShMemLock)
|
||||||
{
|
{
|
||||||
foreach (long Position in ShMemPositions)
|
foreach (long Position in ShMemPositions)
|
||||||
{
|
{
|
||||||
long TouchScreenOffset = Position + HidTouchScreenOffset;
|
WriteTouchPoints(Position, Points);
|
||||||
|
|
||||||
long LastEntry = ReadInt64(TouchScreenOffset + 0x10);
|
|
||||||
|
|
||||||
long CurrEntry = (LastEntry + 1) % HidEntryCount;
|
|
||||||
|
|
||||||
long Timestamp = ReadInt64(TouchScreenOffset) + 1;
|
|
||||||
|
|
||||||
WriteInt64(TouchScreenOffset + 0x0, Timestamp);
|
|
||||||
WriteInt64(TouchScreenOffset + 0x8, HidEntryCount);
|
|
||||||
WriteInt64(TouchScreenOffset + 0x10, CurrEntry);
|
|
||||||
WriteInt64(TouchScreenOffset + 0x18, HidEntryCount - 1);
|
|
||||||
WriteInt64(TouchScreenOffset + 0x20, Timestamp);
|
|
||||||
|
|
||||||
long TouchEntryOffset = TouchScreenOffset + HidTouchHeaderSize;
|
|
||||||
|
|
||||||
long LastEntryOffset = TouchEntryOffset + LastEntry * HidTouchEntrySize;
|
|
||||||
|
|
||||||
TouchEntryOffset += CurrEntry * HidTouchEntrySize;
|
|
||||||
|
|
||||||
WriteInt64(TouchEntryOffset + 0x0, Timestamp);
|
|
||||||
WriteInt64(TouchEntryOffset + 0x8, Points.Length);
|
|
||||||
|
|
||||||
TouchEntryOffset += HidTouchEntryHeaderSize;
|
|
||||||
|
|
||||||
const int Padding = 0;
|
|
||||||
|
|
||||||
int Index = 0;
|
|
||||||
|
|
||||||
foreach (HidTouchPoint Point in Points)
|
|
||||||
{
|
|
||||||
WriteInt64(TouchEntryOffset + 0x0, Timestamp);
|
|
||||||
WriteInt32(TouchEntryOffset + 0x8, Padding);
|
|
||||||
WriteInt32(TouchEntryOffset + 0xc, Index++);
|
|
||||||
WriteInt32(TouchEntryOffset + 0x10, Point.X);
|
|
||||||
WriteInt32(TouchEntryOffset + 0x14, Point.Y);
|
|
||||||
WriteInt32(TouchEntryOffset + 0x18, Point.DiameterX);
|
|
||||||
WriteInt32(TouchEntryOffset + 0x1c, Point.DiameterY);
|
|
||||||
WriteInt32(TouchEntryOffset + 0x20, Point.Angle);
|
|
||||||
WriteInt32(TouchEntryOffset + 0x24, Padding);
|
|
||||||
|
|
||||||
TouchEntryOffset += HidTouchEntryTouchSize;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe long ReadInt64(long Position)
|
private void WriteTouchPoints(long BasePosition, params HidTouchPoint[] Points)
|
||||||
{
|
{
|
||||||
if ((ulong)Position + 8 > AMemoryMgr.AddrSize) return 0;
|
long TouchScreenOffset = BasePosition + HidTouchScreenOffset;
|
||||||
|
|
||||||
return *((long*)((byte*)Ram + Position));
|
long Timestamp = GetTimestamp();
|
||||||
|
|
||||||
|
CurrTouchEntry = (CurrTouchEntry + 1) % HidEntryCount;
|
||||||
|
|
||||||
|
Ns.Memory.WriteInt64(TouchScreenOffset + 0x0, Timestamp);
|
||||||
|
Ns.Memory.WriteInt64(TouchScreenOffset + 0x8, HidEntryCount);
|
||||||
|
Ns.Memory.WriteInt64(TouchScreenOffset + 0x10, CurrTouchEntry);
|
||||||
|
Ns.Memory.WriteInt64(TouchScreenOffset + 0x18, HidEntryCount - 1);
|
||||||
|
Ns.Memory.WriteInt64(TouchScreenOffset + 0x20, Timestamp);
|
||||||
|
|
||||||
|
long TouchEntryOffset = TouchScreenOffset + HidTouchHeaderSize;
|
||||||
|
|
||||||
|
TouchEntryOffset += CurrTouchEntry * HidTouchEntrySize;
|
||||||
|
|
||||||
|
Ns.Memory.WriteInt64(TouchEntryOffset + 0x0, CurrTouchSampleCounter++);
|
||||||
|
Ns.Memory.WriteInt64(TouchEntryOffset + 0x8, Points.Length);
|
||||||
|
|
||||||
|
TouchEntryOffset += HidTouchEntryHeaderSize;
|
||||||
|
|
||||||
|
const int Padding = 0;
|
||||||
|
|
||||||
|
int Index = 0;
|
||||||
|
|
||||||
|
foreach (HidTouchPoint Point in Points)
|
||||||
|
{
|
||||||
|
Ns.Memory.WriteInt64(TouchEntryOffset + 0x0, Timestamp);
|
||||||
|
Ns.Memory.WriteInt32(TouchEntryOffset + 0x8, Padding);
|
||||||
|
Ns.Memory.WriteInt32(TouchEntryOffset + 0xc, Index++);
|
||||||
|
Ns.Memory.WriteInt32(TouchEntryOffset + 0x10, Point.X);
|
||||||
|
Ns.Memory.WriteInt32(TouchEntryOffset + 0x14, Point.Y);
|
||||||
|
Ns.Memory.WriteInt32(TouchEntryOffset + 0x18, Point.DiameterX);
|
||||||
|
Ns.Memory.WriteInt32(TouchEntryOffset + 0x1c, Point.DiameterY);
|
||||||
|
Ns.Memory.WriteInt32(TouchEntryOffset + 0x20, Point.Angle);
|
||||||
|
Ns.Memory.WriteInt32(TouchEntryOffset + 0x24, Padding);
|
||||||
|
|
||||||
|
TouchEntryOffset += HidTouchEntryTouchSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void WriteInt32(long Position, int Value)
|
private long GetTimestamp()
|
||||||
{
|
{
|
||||||
if ((ulong)Position + 4 > AMemoryMgr.AddrSize) return;
|
return Environment.TickCount * 19_200;
|
||||||
|
|
||||||
*((int*)((byte*)Ram + Position)) = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private unsafe void WriteInt64(long Position, long Value)
|
|
||||||
{
|
|
||||||
if ((ulong)Position + 8 > AMemoryMgr.AddrSize) return;
|
|
||||||
|
|
||||||
*((long*)((byte*)Ram + Position)) = Value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,6 +9,9 @@ namespace Ryujinx.Core.OsHle
|
||||||
public const long MapRegionAddress = 0x10000000;
|
public const long MapRegionAddress = 0x10000000;
|
||||||
public const long MapRegionSize = 0x20000000;
|
public const long MapRegionSize = 0x20000000;
|
||||||
|
|
||||||
|
public const long HeapRegionAddress = MapRegionAddress + MapRegionSize;
|
||||||
|
public const long HeapRegionSize = TlsPagesAddress - HeapRegionAddress;
|
||||||
|
|
||||||
public const long MainStackSize = 0x100000;
|
public const long MainStackSize = 0x100000;
|
||||||
|
|
||||||
public const long MainStackAddress = AMemoryMgr.AddrSize - MainStackSize;
|
public const long MainStackAddress = AMemoryMgr.AddrSize - MainStackSize;
|
||||||
|
@ -17,8 +20,6 @@ namespace Ryujinx.Core.OsHle
|
||||||
|
|
||||||
public const long TlsPagesAddress = MainStackAddress - TlsPagesSize;
|
public const long TlsPagesAddress = MainStackAddress - TlsPagesSize;
|
||||||
|
|
||||||
public const long HeapRegionAddress = MapRegionAddress + MapRegionSize;
|
|
||||||
|
|
||||||
public const long TotalMemoryUsed = HeapRegionAddress + TlsPagesSize + MainStackSize;
|
public const long TotalMemoryUsed = HeapRegionAddress + TlsPagesSize + MainStackSize;
|
||||||
|
|
||||||
public const long TotalMemoryAvailable = AMemoryMgr.RamSize - AddrSpaceStart;
|
public const long TotalMemoryAvailable = AMemoryMgr.RamSize - AddrSpaceStart;
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace Ryujinx.Core.OsHle
|
||||||
this.Ns = Ns;
|
this.Ns = Ns;
|
||||||
this.ProcessId = ProcessId;
|
this.ProcessId = ProcessId;
|
||||||
|
|
||||||
Memory = new AMemory(Ns.Ram);
|
Memory = Ns.Memory;
|
||||||
|
|
||||||
Scheduler = new KProcessScheduler();
|
Scheduler = new KProcessScheduler();
|
||||||
|
|
||||||
|
|
|
@ -264,11 +264,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
||||||
int FbWidth = BufferQueue[Slot].Data.Width;
|
int FbWidth = BufferQueue[Slot].Data.Width;
|
||||||
int FbHeight = BufferQueue[Slot].Data.Height;
|
int FbHeight = BufferQueue[Slot].Data.Height;
|
||||||
|
|
||||||
int FbSize = FbWidth * FbHeight * 4;
|
long FbSize = (uint)FbWidth * FbHeight * 4;
|
||||||
|
|
||||||
HNvMap NvMap = GetNvMap(Context, Slot);
|
HNvMap NvMap = GetNvMap(Context, Slot);
|
||||||
|
|
||||||
if (FbSize < 0 || NvMap.Address < 0 || NvMap.Address + FbSize > AMemoryMgr.AddrSize)
|
if ((ulong)(NvMap.Address + FbSize) > AMemoryMgr.AddrSize)
|
||||||
{
|
{
|
||||||
Logging.Error($"Frame buffer address {NvMap.Address:x16} is invalid!");
|
Logging.Error($"Frame buffer address {NvMap.Address:x16} is invalid!");
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
||||||
Rotate = -MathF.PI * 0.5f;
|
Rotate = -MathF.PI * 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte* Fb = (byte*)Context.Ns.Ram + NvMap.Address;
|
byte* Fb = (byte*)Context.Ns.Memory.Ram + NvMap.Address;
|
||||||
|
|
||||||
Context.Ns.Gpu.Renderer.QueueAction(delegate()
|
Context.Ns.Gpu.Renderer.QueueAction(delegate()
|
||||||
{
|
{
|
||||||
|
|
|
@ -197,7 +197,7 @@ namespace Ryujinx.Core.OsHle.Svc
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
ThreadState.X1 = CurrentHeapSize;
|
ThreadState.X1 = MemoryRegions.HeapRegionSize;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
using System;
|
using System.Diagnostics;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Text;
|
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
|
|
||||||
namespace Ryujinx.Core
|
namespace Ryujinx.Core
|
||||||
|
|
|
@ -5,13 +5,12 @@ using Ryujinx.Core.Settings;
|
||||||
using Ryujinx.Graphics.Gal;
|
using Ryujinx.Graphics.Gal;
|
||||||
using Ryujinx.Graphics.Gpu;
|
using Ryujinx.Graphics.Gpu;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Core
|
namespace Ryujinx.Core
|
||||||
{
|
{
|
||||||
public class Switch : IDisposable
|
public class Switch : IDisposable
|
||||||
{
|
{
|
||||||
public IntPtr Ram {get; private set; }
|
internal AMemory Memory { get; private set; }
|
||||||
|
|
||||||
internal NsGpu Gpu { get; private set; }
|
internal NsGpu Gpu { get; private set; }
|
||||||
internal Horizon Os { get; private set; }
|
internal Horizon Os { get; private set; }
|
||||||
|
@ -25,13 +24,13 @@ namespace Ryujinx.Core
|
||||||
|
|
||||||
public Switch(IGalRenderer Renderer)
|
public Switch(IGalRenderer Renderer)
|
||||||
{
|
{
|
||||||
Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
|
Memory = new AMemory();
|
||||||
|
|
||||||
Gpu = new NsGpu(Renderer);
|
Gpu = new NsGpu(Renderer);
|
||||||
|
|
||||||
VFs = new VirtualFs();
|
VFs = new VirtualFs();
|
||||||
|
|
||||||
Hid = new Hid(Ram);
|
Hid = new Hid(this);
|
||||||
|
|
||||||
Statistics = new PerformanceStatistics();
|
Statistics = new PerformanceStatistics();
|
||||||
|
|
||||||
|
@ -72,10 +71,10 @@ namespace Ryujinx.Core
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
|
Memory.Dispose();
|
||||||
|
|
||||||
VFs.Dispose();
|
VFs.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Marshal.FreeHGlobal(Ram);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,8 +2,6 @@ using ChocolArm64;
|
||||||
using ChocolArm64.Memory;
|
using ChocolArm64.Memory;
|
||||||
using ChocolArm64.State;
|
using ChocolArm64.State;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
|
@ -16,7 +14,6 @@ namespace Ryujinx.Tests.Cpu
|
||||||
|
|
||||||
private long EntryPoint;
|
private long EntryPoint;
|
||||||
|
|
||||||
private IntPtr Ram;
|
|
||||||
private AMemory Memory;
|
private AMemory Memory;
|
||||||
private AThread Thread;
|
private AThread Thread;
|
||||||
|
|
||||||
|
@ -28,9 +25,8 @@ namespace Ryujinx.Tests.Cpu
|
||||||
|
|
||||||
EntryPoint = Position;
|
EntryPoint = Position;
|
||||||
|
|
||||||
Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
|
|
||||||
ATranslator Translator = new ATranslator();
|
ATranslator Translator = new ATranslator();
|
||||||
Memory = new AMemory(Ram);
|
Memory = new AMemory();
|
||||||
Memory.Manager.Map(Position, Size, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute);
|
Memory.Manager.Map(Position, Size, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute);
|
||||||
Thread = new AThread(Translator, Memory, ThreadPriority.Normal, EntryPoint);
|
Thread = new AThread(Translator, Memory, ThreadPriority.Normal, EntryPoint);
|
||||||
}
|
}
|
||||||
|
@ -38,9 +34,9 @@ namespace Ryujinx.Tests.Cpu
|
||||||
[TearDown]
|
[TearDown]
|
||||||
public void Teardown()
|
public void Teardown()
|
||||||
{
|
{
|
||||||
|
Memory.Dispose();
|
||||||
Thread = null;
|
Thread = null;
|
||||||
Memory = null;
|
Memory = null;
|
||||||
Marshal.FreeHGlobal(Ram);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Reset()
|
protected void Reset()
|
||||||
|
|
Loading…
Reference in a new issue