* 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:
feos 2020-03-11 18:53:42 +03:00 committed by GitHub
parent 7456d81a9c
commit 9dd9b4cc0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 194 additions and 17 deletions
BizHawk.Client.EmuHawk/tools/HexEditor
BizHawk.Emulation.Common/Base Implementations

View File

@ -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)

View File

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

View File

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