bad attempt at wiring up mGBA memory hooks

This commit is contained in:
adelikat 2020-02-23 13:23:38 -06:00
parent 0422b9b1de
commit 75a991a36d
3 changed files with 113 additions and 1 deletions

View File

@ -143,5 +143,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
[DllImport(dll, CallingConvention = cc)]
public static extern void BizSetTraceCallback(TraceCallback cb);
public enum mWatchpointType {
WATCHPOINT_WRITE = 1,
WATCHPOINT_READ = 2,
WATCHPOINT_RW = 3,
WATCHPOINT_WRITE_CHANGE = 4,
};
[UnmanagedFunctionPointer(cc)]
public delegate void MemCallback(uint addr, mWatchpointType type, uint oldValue, uint newValue);
[DllImport(dll, CallingConvention = cc)]
public static extern void BizSetMemCallback(MemCallback cb);
}
}

View File

@ -27,7 +27,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
}
[FeatureNotImplemented]
public IMemoryCallbackSystem MemoryCallbacks => throw new NotImplementedException();
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MGBAMemoryCallbackSystem();
public bool CanStep(StepType type) => false;

View File

@ -0,0 +1,100 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBA
{
public class MGBAMemoryCallbackSystem : IMemoryCallbackSystem
{
private readonly List<CallbackContainer> _callbacks = new List<CallbackContainer>();
public string[] AvailableScopes { get; } = { "System Bus" };
public bool ExecuteCallbacksAvailable => false;
public bool HasReads => _callbacks.Any(c => c.Callback.Type == MemoryCallbackType.Read);
public bool HasWrites => _callbacks.Any(c => c.Callback.Type == MemoryCallbackType.Write);
public bool HasExecutes => _callbacks.Any(c => c.Callback.Type == MemoryCallbackType.Execute);
public bool HasReadsForScope(string scope) =>
_callbacks.Any(c => c.Callback.Scope == scope
&& c.Callback.Type == MemoryCallbackType.Read);
public bool HasWritesForScope(string scope) =>
_callbacks.Any(c => c.Callback.Scope == scope
&& c.Callback.Type == MemoryCallbackType.Write);
public bool HasExecutesForScope(string scope) =>
_callbacks.Any(c => c.Callback.Scope == scope
&& c.Callback.Type == MemoryCallbackType.Execute);
public void Add(IMemoryCallback callback)
{
if (!AvailableScopes.Contains(callback.Scope))
{
throw new InvalidOperationException($"{callback.Scope} is not currently supported for callbacks");
}
var container = new CallbackContainer(callback);
LibmGBA.BizSetMemCallback(container.Call);
_callbacks.Add(container);
}
public void Remove(MemoryCallbackDelegate action)
{
// TODO
}
public void RemoveAll(IEnumerable<MemoryCallbackDelegate> actions)
{
// TODO
}
public void Clear()
{
// TODO
}
public IEnumerator<IMemoryCallback> GetEnumerator() => _callbacks.Select(c => c.Callback).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _callbacks.Select(c => c.Callback).GetEnumerator();
public void CallMemoryCallbacks(uint addr, uint value, uint flags, string scope)
{
// Not a thing in this implementation
}
}
internal class CallbackContainer
{
public CallbackContainer(IMemoryCallback callBack)
{
Callback = callBack;
}
public IMemoryCallback Callback { get; }
public LibmGBA.mWatchpointType WatchPointType
{
get
{
switch (Callback.Type)
{
default:
case MemoryCallbackType.Read:
return LibmGBA.mWatchpointType.WATCHPOINT_READ;
case MemoryCallbackType.Write:
return LibmGBA.mWatchpointType.WATCHPOINT_WRITE;
case MemoryCallbackType.Execute:
throw new NotImplementedException("Executes not implemented yet");
}
}
}
public void Call(uint addr, LibmGBA.mWatchpointType type, uint oldValue, uint newValue)
{
Callback.Callback?.Invoke(addr, newValue, 0);
}
}
}