Bulkread (#1834)
* POC of a memory domain bulk read concept, wired up to hex editor, very sloppy currently * do the todo * delegates for bulkreads * refactor bulk reads to take in a range and a pre-allocated array for the values Co-authored-by: adelikat <adelikat@tasvideos.org>
This commit is contained in:
parent
7456d81a9c
commit
9dd9b4cc0d
BizHawk.Client.EmuHawk/tools/HexEditor
BizHawk.Emulation.Common/Base Implementations
|
@ -517,7 +517,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
private string GenerateMemoryViewString(bool forWindow)
|
||||
{
|
||||
var rowStr = new StringBuilder();
|
||||
|
||||
var test = MakeValues();
|
||||
for (var i = 0; i < _rowsVisible; i++)
|
||||
{
|
||||
_row = i + HexScrollBar.Value;
|
||||
|
@ -531,21 +531,23 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (_addr + j + DataSize <= _domain.Size)
|
||||
{
|
||||
int tVal = 0;
|
||||
for (int k = 0; k < DataSize; k++)
|
||||
{
|
||||
int tNext = MakeValue(1, _addr + j + k);
|
||||
if (BigEndian)
|
||||
{
|
||||
tVal += (tNext << (k * 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
tVal += (tNext << ((DataSize - k - 1) * 8));
|
||||
}
|
||||
}
|
||||
var addressVal = test[_addr + j];
|
||||
rowStr.AppendFormat(_digitFormatString, addressVal);
|
||||
//int tVal = 0;
|
||||
//for (int k = 0; k < DataSize; k++)
|
||||
//{
|
||||
// int tNext = MakeValue(1, _addr + j + k);
|
||||
// if (BigEndian)
|
||||
// {
|
||||
// tVal += (tNext << (k * 8));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// tVal += (tNext << ((DataSize - k - 1) * 8));
|
||||
// }
|
||||
//}
|
||||
|
||||
rowStr.AppendFormat(_digitFormatString, tVal);
|
||||
//rowStr.AppendFormat(_digitFormatString, tVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -577,6 +579,70 @@ namespace BizHawk.Client.EmuHawk
|
|||
return rowStr.ToString();
|
||||
}
|
||||
|
||||
private Dictionary<long, long> MakeValues()
|
||||
{
|
||||
var addresses = new List<long>();
|
||||
|
||||
for (var i = 0; i < _rowsVisible; i++)
|
||||
{
|
||||
_row = i + HexScrollBar.Value;
|
||||
_addr = _row << 4;
|
||||
if (_addr >= _domain.Size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (var j = 0; j < 16; j += DataSize)
|
||||
{
|
||||
if (_addr + j + DataSize <= _domain.Size)
|
||||
{
|
||||
var address = _addr + j;
|
||||
addresses.Add(address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<long, long> dict = new Dictionary<long, long>();
|
||||
var range = new MutableRange<long>(addresses[0], addresses[0] + addresses.Count);
|
||||
|
||||
switch (DataSize)
|
||||
{
|
||||
default:
|
||||
case 1:
|
||||
{
|
||||
var vals = new byte[addresses.Count];
|
||||
_domain.BulkPeekByte(range, vals);
|
||||
for (var i = 0; i < addresses.Count; i++)
|
||||
{
|
||||
dict.Add(addresses[i], vals[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
var vals = new ushort[addresses.Count];
|
||||
_domain.BulkPeekUshort(range, BigEndian, vals);
|
||||
for (var i = 0; i < addresses.Count; i++)
|
||||
{
|
||||
dict.Add(addresses[i], vals[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
var vals = new uint[addresses.Count];
|
||||
_domain.BulkPeekUint(range, BigEndian, vals);
|
||||
for (var i = 0; i < addresses.Count; i++)
|
||||
{
|
||||
dict.Add(addresses[i], vals[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
private byte MakeByte(long address)
|
||||
{
|
||||
return Global.CheatList.IsActive(_domain, address)
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
namespace BizHawk.Emulation.Common
|
||||
using System;
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// A memory region and the functionality to read/write from it
|
||||
|
@ -100,5 +103,59 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BulkPeekByte(Range<long> addresses, byte[] values)
|
||||
{
|
||||
if (addresses == null || values == null)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
if (addresses.EndInclusive - addresses.Start != values.Length)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid length of values array");
|
||||
}
|
||||
|
||||
for (var i = addresses.Start; i < addresses.EndInclusive; i++)
|
||||
{
|
||||
values[i] = PeekByte(i);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BulkPeekUshort(Range<long> addresses, bool bigEndian, ushort[] values)
|
||||
{
|
||||
if (addresses == null || values == null)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
if (addresses.EndInclusive - addresses.Start != values.Length)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid length of values array");
|
||||
}
|
||||
|
||||
for (var i = addresses.Start; i < addresses.EndInclusive; i++)
|
||||
{
|
||||
values[i] = PeekUshort(i, bigEndian);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void BulkPeekUint(Range<long> addresses, bool bigEndian, uint[] values)
|
||||
{
|
||||
if (addresses == null || values == null)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
if (addresses.EndInclusive - addresses.Start != values.Length)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid length of values array");
|
||||
}
|
||||
|
||||
for (var i = addresses.Start; i < addresses.EndInclusive; i++)
|
||||
{
|
||||
values[i] = PeekUint(i, bigEndian);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using BizHawk.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Emulation.Common
|
||||
{
|
||||
|
@ -7,6 +8,11 @@ namespace BizHawk.Emulation.Common
|
|||
{
|
||||
private Action<long, byte> _poke;
|
||||
|
||||
// TODO: use an array of Ranges
|
||||
private Action<Range<long>, byte[]> _bulkPeekByte { get; set; }
|
||||
private Action<Range<long>, bool, ushort[]> _bulkPeekUshort { get; set; }
|
||||
private Action<Range<long>, bool, uint[]> _bulkPeekUint { get; set; }
|
||||
|
||||
public Func<long, byte> Peek { get; set; }
|
||||
|
||||
public Action<long, byte> Poke
|
||||
|
@ -29,7 +35,52 @@ namespace BizHawk.Emulation.Common
|
|||
_poke?.Invoke(addr, val);
|
||||
}
|
||||
|
||||
public MemoryDomainDelegate(string name, long size, Endian endian, Func<long, byte> peek, Action<long, byte> poke, int wordSize)
|
||||
public override void BulkPeekByte(Range<long> addresses, byte[] values)
|
||||
{
|
||||
if (_bulkPeekByte != null)
|
||||
{
|
||||
_bulkPeekByte.Invoke(addresses, values);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.BulkPeekByte(addresses, values);
|
||||
}
|
||||
}
|
||||
|
||||
public override void BulkPeekUshort(Range<long> addresses, bool bigEndian, ushort[] values)
|
||||
{
|
||||
if (_bulkPeekUshort != null)
|
||||
{
|
||||
_bulkPeekUshort.Invoke(addresses, EndianType == Endian.Big, values);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.BulkPeekUshort(addresses, EndianType == Endian.Big, values);
|
||||
}
|
||||
}
|
||||
|
||||
public override void BulkPeekUint(Range<long> addresses, bool bigEndian, uint[] values)
|
||||
{
|
||||
if (_bulkPeekUint != null)
|
||||
{
|
||||
_bulkPeekUint.Invoke(addresses, EndianType == Endian.Big, values);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.BulkPeekUint(addresses, EndianType == Endian.Big, values);
|
||||
}
|
||||
}
|
||||
|
||||
public MemoryDomainDelegate(
|
||||
string name,
|
||||
long size,
|
||||
Endian endian,
|
||||
Func<long, byte> peek,
|
||||
Action<long, byte> poke,
|
||||
int wordSize,
|
||||
Action<Range<long>, byte[]> bulkPeekByte = null,
|
||||
Action<Range<long>, bool, ushort[]> bulkPeekUshort = null,
|
||||
Action<Range<long>, bool, uint[]> bulkPeekUint = null)
|
||||
{
|
||||
Name = name;
|
||||
EndianType = endian;
|
||||
|
@ -38,6 +89,9 @@ namespace BizHawk.Emulation.Common
|
|||
_poke = poke;
|
||||
Writable = poke != null;
|
||||
WordSize = wordSize;
|
||||
_bulkPeekByte = bulkPeekByte;
|
||||
_bulkPeekUshort = bulkPeekUshort;
|
||||
_bulkPeekUint = bulkPeekUint;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue