2014-12-05 01:56:45 +00:00
using System ;
using System.Collections.Generic ;
namespace BizHawk.Emulation.Common
{
2019-06-06 09:04:47 +00:00
public delegate void MemoryCallbackDelegate ( uint address , uint value , uint flags ) ;
2016-12-14 15:11:07 +00:00
/// <summary>
2017-04-27 16:56:33 +00:00
/// This is a property of <seealso cref="IDebuggable"/>, and defines the means by which a client
2016-12-14 15:11:07 +00:00
/// gets and sets memory callbacks in the core. A memory callback should fire any time memory is
/// read/written/executed by the core, and depends on the type specified by the callback
/// </summary>
/// <seealso cref="IDebuggable"/>
2014-12-07 19:38:42 +00:00
public interface IMemoryCallbackSystem : IEnumerable < IMemoryCallback >
2014-12-05 01:56:45 +00:00
{
2014-12-17 01:20:53 +00:00
/ *
* DANGER :
* Many cores will blindly call CallReads ( ) , CallWrites ( ) , CallExecutes ( ) on every rwx no matter what .
* These functions must return very quickly if the list is empty . Very very quickly .
* /
2015-01-25 22:14:58 +00:00
/// <summary>
2017-04-26 14:10:00 +00:00
/// Gets a value indicating whether or not Execute callbacks are available for this this implementation
2015-01-25 22:14:58 +00:00
/// </summary>
bool ExecuteCallbacksAvailable { get ; }
2014-12-05 01:56:45 +00:00
/// <summary>
2017-04-26 14:10:00 +00:00
/// Gets a value indicating whether or not there are currently any read hooks
2014-12-05 01:56:45 +00:00
/// </summary>
bool HasReads { get ; }
/// <summary>
2017-04-26 14:10:00 +00:00
/// Gets a value indicating whether or not there are currently any write hooks
2014-12-05 01:56:45 +00:00
/// </summary>
bool HasWrites { get ; }
/// <summary>
2017-04-26 14:10:00 +00:00
/// Gets a value indicating whether or not there are currently any execute hooks
2014-12-05 01:56:45 +00:00
/// </summary>
bool HasExecutes { get ; }
2017-08-23 14:08:43 +00:00
/// <summary>
/// Gets a value indicating whether or not there are currently any read hooks
/// </summary>
bool HasReadsForScope ( string scope ) ;
/// <summary>
/// Gets a value indicating whether or not there are currently any write hooks
/// </summary>
bool HasWritesForScope ( string scope ) ;
/// <summary>
/// Gets a value indicating whether or not there are currently any execute hooks
/// </summary>
bool HasExecutesForScope ( string scope ) ;
2014-12-05 01:56:45 +00:00
/// <summary>
2014-12-07 18:53:56 +00:00
/// Adds a callback for the given type to the given address
2014-12-05 01:56:45 +00:00
/// If no address is specified the callback will be hooked to all addresses
2014-12-07 18:53:56 +00:00
/// Note: an execute callback can not be added without an address, else an InvalidOperationException will occur
2014-12-05 01:56:45 +00:00
/// </summary>
2017-08-04 01:03:40 +00:00
/// <exception cref="InvalidCastException">Thrown when the <see cref="IMemoryCallback.Scope"/> property of the <see cref="IMemoryCallback"/> is not in the <see cref="AvailableScopes"/></exception>
2014-12-07 19:09:36 +00:00
void Add ( IMemoryCallback callback ) ;
2014-12-05 01:56:45 +00:00
/// <summary>
2019-06-06 09:04:47 +00:00
/// Executes all matching callbacks for the given address and domain
2014-12-05 01:56:45 +00:00
/// </summary>
2017-08-04 01:03:40 +00:00
/// <param name="addr">The address to check for callbacks</param>
2019-06-06 09:04:47 +00:00
/// <param name="value">The value contained (or written to) addr</param>
/// <param name="flags">The callback flags relevant to this access</param>
2019-05-29 10:58:01 +00:00
/// <param name="scope">The scope that the address pertains to. Must be a value in <see cref="AvailableScopes"/></param>
2019-06-06 09:04:47 +00:00
void CallMemoryCallbacks ( uint addr , uint value , uint flags , string scope ) ;
2014-12-05 01:56:45 +00:00
/// <summary>
/// Removes the given callback from the list
/// </summary>
2019-06-06 09:04:47 +00:00
void Remove ( MemoryCallbackDelegate action ) ;
2014-12-05 01:56:45 +00:00
/// <summary>
/// Removes the given callbacks from the list
/// </summary>
2019-06-06 09:04:47 +00:00
void RemoveAll ( IEnumerable < MemoryCallbackDelegate > actions ) ;
2014-12-05 01:56:45 +00:00
/// <summary>
/// Removes all read,write, and execute callbacks
/// </summary>
void Clear ( ) ;
2017-08-02 03:05:17 +00:00
/// <summary>
2017-08-04 01:03:40 +00:00
/// A list of available "scopes" (memory domains, cpus, etc) that a the <see cref="IMemoryCallback.Scope"/> property of the <see cref="IMemoryCallback"/> can have
2017-08-02 03:05:17 +00:00
/// Passing a <see cref="IMemoryCallback"/> into the <see cref="Add(IMemoryCallback)"/> method that is not in this list will result in an <seealso cref="InvalidOperationException"/>
/// </summary>
2017-08-04 01:03:40 +00:00
string [ ] AvailableScopes { get ; }
2014-12-05 01:56:45 +00:00
}
2014-12-07 18:53:56 +00:00
2016-12-14 15:11:07 +00:00
/// <summary>
/// This service defines a memory callback used by an IMemoryCallbackSystem implementation
/// </summary>
/// <seealso cref="IMemoryCallbackSystem"/>
2014-12-07 19:09:36 +00:00
public interface IMemoryCallback
{
MemoryCallbackType Type { get ; }
string Name { get ; }
2019-06-06 09:04:47 +00:00
MemoryCallbackDelegate Callback { get ; }
2014-12-07 19:09:36 +00:00
uint? Address { get ; }
2016-08-08 11:37:39 +00:00
uint? AddressMask { get ; }
2017-08-04 01:03:40 +00:00
string Scope { get ; }
2014-12-07 19:09:36 +00:00
}
2017-05-02 12:44:23 +00:00
public enum MemoryCallbackType
{
Read , Write , Execute
}
2019-06-06 09:04:47 +00:00
[Flags]
public enum MemoryCallbackFlags : uint
{
SizeUnknown = 0x00 < < 16 ,
SizeByte = 0x01 < < 16 ,
SizeWord = 0x02 < < 16 ,
SizeLong = 0x03 < < 16 ,
AccessUnknown = 0x00 < < 12 ,
AccessRead = 0x01 < < 12 ,
AccessWrite = 0x02 < < 12 ,
AccessExecute = 0x04 < < 12 ,
CPUUnknown = 0x00 < < 8 ,
CPUZero = 0x01 < < 8 ,
DomainUnknown = 0x00 ,
}
2014-12-05 01:56:45 +00:00
}