aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Memory/MemoryManager.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-01-12 20:27:50 -0300
committerjduncanator <1518948+jduncanator@users.noreply.github.com>2020-01-13 10:27:50 +1100
commitb8e3909d800ff5947683bb169d8efda2ef63d697 (patch)
tree653a2e60b42cb45fbeb1ad76aa6b827bc1e38966 /ARMeilleure/Memory/MemoryManager.cs
parent8b90924c1ebf7e65d1f170df5dd1ac6c2596926f (diff)
Add a GetSpan method to the memory manager and use it on GPU (#877)
Diffstat (limited to 'ARMeilleure/Memory/MemoryManager.cs')
-rw-r--r--ARMeilleure/Memory/MemoryManager.cs45
1 files changed, 45 insertions, 0 deletions
diff --git a/ARMeilleure/Memory/MemoryManager.cs b/ARMeilleure/Memory/MemoryManager.cs
index f813bd7e..e4e8b2d2 100644
--- a/ARMeilleure/Memory/MemoryManager.cs
+++ b/ARMeilleure/Memory/MemoryManager.cs
@@ -1,6 +1,7 @@
using ARMeilleure.State;
using System;
using System.Collections.Generic;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
@@ -552,6 +553,50 @@ namespace ARMeilleure.Memory
return data;
}
+ public ReadOnlySpan<byte> GetSpan(ulong address, ulong size)
+ {
+ if (IsContiguous(address, size))
+ {
+ return new ReadOnlySpan<byte>((void*)Translate((long)address), (int)size);
+ }
+ else
+ {
+ return ReadBytes((long)address, (long)size);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private bool IsContiguous(ulong address, ulong size)
+ {
+ if (!IsValidPosition((long)address))
+ {
+ return false;
+ }
+
+ ulong endVa = (address + size + PageMask) & ~(ulong)PageMask;
+
+ address &= ~(ulong)PageMask;
+
+ int pages = (int)((endVa - address) / PageSize);
+
+ for (int page = 0; page < pages - 1; page++)
+ {
+ if (!IsValidPosition((long)address + PageSize))
+ {
+ return false;
+ }
+
+ if (GetPtEntry((long)address) + PageSize != GetPtEntry((long)address + PageSize))
+ {
+ return false;
+ }
+
+ address += PageSize;
+ }
+
+ return true;
+ }
+
public void WriteSByte(long position, sbyte value)
{
WriteByte(position, (byte)value);