Move MemoryCallbackSystem from CoreComm to IDebuggable and refactor accordingly, Lua - tell the user when memory callbacks are not available for a given core

This commit is contained in:
adelikat 2014-12-05 01:56:45 +00:00
parent 11a8a009c5
commit 0b84beec88
37 changed files with 433 additions and 213 deletions

View File

@ -124,6 +124,11 @@ namespace BizHawk.Client.Common
} }
} }
private void LogMemoryCallbacksNotImplemented()
{
Log(string.Format("{0} does not implement memory callbacks"));
}
#endregion #endregion
[LuaMethodAttributes( [LuaMethodAttributes(
@ -196,10 +201,19 @@ namespace BizHawk.Client.Common
)] )]
public string OnMemoryExecute(LuaFunction luaf, uint address, string name = null) public string OnMemoryExecute(LuaFunction luaf, uint address, string name = null)
{ {
var nlf = new NamedLuaFunction(luaf, "OnMemoryExecute", LogOutputCallback, CurrentThread, name); if (Global.Emulator.MemoryCallbacksAvailable())
_luaFunctions.Add(nlf); {
Global.CoreComm.MemoryCallbackSystem.AddExecute(nlf.Callback, address); var nlf = new NamedLuaFunction(luaf, "OnMemoryExecute", LogOutputCallback, CurrentThread, name);
return nlf.Guid.ToString(); _luaFunctions.Add(nlf);
Global.Emulator.AsDebuggable().MemoryCallbacks.AddExecute(nlf.Callback, address);
return nlf.Guid.ToString();
}
else
{
LogMemoryCallbacksNotImplemented();
return Guid.Empty.ToString();
}
} }
[LuaMethodAttributes( [LuaMethodAttributes(
@ -208,10 +222,18 @@ namespace BizHawk.Client.Common
)] )]
public string OnMemoryRead(LuaFunction luaf, uint? address = null, string name = null) public string OnMemoryRead(LuaFunction luaf, uint? address = null, string name = null)
{ {
var nlf = new NamedLuaFunction(luaf, "OnMemoryRead", LogOutputCallback, CurrentThread, name); if (Global.Emulator.MemoryCallbacksAvailable())
_luaFunctions.Add(nlf); {
Global.CoreComm.MemoryCallbackSystem.AddRead(nlf.Callback, address); var nlf = new NamedLuaFunction(luaf, "OnMemoryRead", LogOutputCallback, CurrentThread, name);
return nlf.Guid.ToString(); _luaFunctions.Add(nlf);
Global.Emulator.AsDebuggable().MemoryCallbacks.AddRead(nlf.Callback, address);
return nlf.Guid.ToString();
}
else
{
LogMemoryCallbacksNotImplemented();
return Guid.Empty.ToString();
}
} }
[LuaMethodAttributes( [LuaMethodAttributes(
@ -220,10 +242,18 @@ namespace BizHawk.Client.Common
)] )]
public string OnMemoryWrite(LuaFunction luaf, uint? address = null, string name = null) public string OnMemoryWrite(LuaFunction luaf, uint? address = null, string name = null)
{ {
var nlf = new NamedLuaFunction(luaf, "OnMemoryWrite", LogOutputCallback, CurrentThread, name); if (Global.Emulator.MemoryCallbacksAvailable())
_luaFunctions.Add(nlf); {
Global.CoreComm.MemoryCallbackSystem.AddWrite(nlf.Callback, address); var nlf = new NamedLuaFunction(luaf, "OnMemoryWrite", LogOutputCallback, CurrentThread, name);
return nlf.Guid.ToString(); _luaFunctions.Add(nlf);
Global.Emulator.AsDebuggable().MemoryCallbacks.AddWrite(nlf.Callback, address);
return nlf.Guid.ToString();
}
else
{
LogMemoryCallbacksNotImplemented();
return Guid.Empty.ToString();
}
} }
[LuaMethodAttributes( [LuaMethodAttributes(

View File

@ -23,7 +23,11 @@ namespace BizHawk.Client.Common
Global.Emulator.AsInputPollable().InputCallbacks.Remove(function.Callback); Global.Emulator.AsInputPollable().InputCallbacks.Remove(function.Callback);
} }
Global.Emulator.CoreComm.MemoryCallbackSystem.Remove(function.Callback); if (Global.Emulator.CanDebug())
{
Global.Emulator.AsDebuggable().MemoryCallbacks.Remove(function.Callback);
}
return base.Remove(function); return base.Remove(function);
} }
@ -34,7 +38,11 @@ namespace BizHawk.Client.Common
Global.Emulator.AsInputPollable().InputCallbacks.RemoveAll(this.Select(x => x.Callback)); Global.Emulator.AsInputPollable().InputCallbacks.RemoveAll(this.Select(x => x.Callback));
} }
Global.Emulator.CoreComm.MemoryCallbackSystem.RemoveAll(this.Select(x => x.Callback)); if (Global.Emulator.CanDebug())
{
Global.Emulator.AsDebuggable().MemoryCallbacks.RemoveAll(this.Select(x => x.Callback));
}
Clear(); Clear();
} }
} }

View File

@ -394,7 +394,7 @@ namespace BizHawk.Client.EmuHawk
var b = new AddBreakpointDialog(); var b = new AddBreakpointDialog();
if (b.ShowDialog() == DialogResult.OK) if (b.ShowDialog() == DialogResult.OK)
{ {
Breakpoints.Add(b.Address, b.BreakType); Breakpoints.Add(_core, b.Address, b.BreakType);
} }
BreakpointView.ItemCount = Breakpoints.Count; BreakpointView.ItemCount = Breakpoints.Count;
@ -446,18 +446,21 @@ namespace BizHawk.Client.EmuHawk
{ {
public Action Callback { get; set; } public Action Callback { get; set; }
public void Add(uint address, BreakpointType type) public void Add(Atari2600 core, uint address, BreakpointType type)
{ {
Add(new AtariBreakpoint(Callback, address, type)); Add(new AtariBreakpoint(core, Callback, address, type));
} }
} }
public class AtariBreakpoint public class AtariBreakpoint
{ {
private bool _active; private bool _active;
private readonly Atari2600 _core;
public AtariBreakpoint(Action callBack, uint address, BreakpointType type, bool enabled = true) public AtariBreakpoint(Atari2600 core, Action callBack, uint address, BreakpointType type, bool enabled = true)
{ {
_core = core;
Callback = callBack; Callback = callBack;
Address = address; Address = address;
Active = enabled; Active = enabled;
@ -500,20 +503,20 @@ namespace BizHawk.Client.EmuHawk
switch (Type) switch (Type)
{ {
case BreakpointType.Read: case BreakpointType.Read:
Global.CoreComm.MemoryCallbackSystem.AddRead(Callback, Address); _core.MemoryCallbacks.AddRead(Callback, Address);
break; break;
case BreakpointType.Write: case BreakpointType.Write:
Global.CoreComm.MemoryCallbackSystem.AddWrite(Callback, Address); _core.MemoryCallbacks.AddWrite(Callback, Address);
break; break;
case BreakpointType.Execute: case BreakpointType.Execute:
Global.CoreComm.MemoryCallbackSystem.AddExecute(Callback, Address); _core.MemoryCallbacks.AddExecute(Callback, Address);
break; break;
} }
} }
private void RemoveCallback() private void RemoveCallback()
{ {
Global.CoreComm.MemoryCallbackSystem.Remove(Callback); _core.MemoryCallbacks.Remove(Callback);
} }
} }

View File

@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Common
{
public class MemoryCallbackSystem : IMemoryCallbackSystem
{
private readonly List<Action> _reads = new List<Action>();
private readonly List<uint?> _readAddrs = new List<uint?>();
private readonly List<Action> _writes = new List<Action>();
private readonly List<uint?> _writeAddrs = new List<uint?>();
private readonly List<Action> _executes = new List<Action>();
private readonly List<uint> _execAddrs = new List<uint>();
public void AddRead(Action function, uint? addr)
{
_reads.Add(function);
_readAddrs.Add(addr);
}
public void AddWrite(Action function, uint? addr)
{
_writes.Add(function);
_writeAddrs.Add(addr);
}
public void AddExecute(Action function, uint addr)
{
_executes.Add(function);
_execAddrs.Add(addr);
}
public void CallRead(uint addr)
{
for (int i = 0; i < _reads.Count; i++)
{
if (!_readAddrs[i].HasValue || _readAddrs[i].Value == addr)
{
_reads[i]();
}
}
}
public void CallWrite(uint addr)
{
for (int i = 0; i < _writes.Count; i++)
{
if (!_writeAddrs[i].HasValue || _writeAddrs[i] == addr)
{
_writes[i]();
}
}
}
public void CallExecute(uint addr)
{
for (int i = 0; i < _executes.Count; i++)
{
if (_execAddrs[i] == addr)
{
_executes[i]();
}
}
}
public bool HasReads { get { return _reads.Any(); } }
public bool HasWrites { get { return _writes.Any(); } }
public bool HasExecutes { get { return _executes.Any(); } }
public void Remove(Action action)
{
for (int i = 0; i < _reads.Count; i++)
{
if (_reads[i] == action)
{
_reads.Remove(_reads[i]);
_readAddrs.Remove(_readAddrs[i]);
}
}
for (int i = 0; i < _writes.Count; i++)
{
if (_writes[i] == action)
{
_writes.Remove(_writes[i]);
_writeAddrs.Remove(_writeAddrs[i]);
}
}
for (int i = 0; i < _executes.Count; i++)
{
if (_executes[i] == action)
{
_executes.Remove(_executes[i]);
_execAddrs.Remove(_execAddrs[i]);
}
}
}
public void RemoveAll(IEnumerable<Action> actions)
{
foreach (var action in actions)
{
Remove(action);
}
}
public void Clear()
{
_reads.Clear();
_readAddrs.Clear();
_writes.Clear();
_writes.Clear();
_executes.Clear();
_execAddrs.Clear();
}
}
}

View File

@ -52,6 +52,7 @@
<Compile Include="Base Implementations\BasicServiceProvider.cs" /> <Compile Include="Base Implementations\BasicServiceProvider.cs" />
<Compile Include="Base Implementations\ControllerDefinition.cs" /> <Compile Include="Base Implementations\ControllerDefinition.cs" />
<Compile Include="Base Implementations\InputCallbackSystem.cs" /> <Compile Include="Base Implementations\InputCallbackSystem.cs" />
<Compile Include="Base Implementations\MemoryCallbackSystem.cs" />
<Compile Include="Base Implementations\NullController.cs" /> <Compile Include="Base Implementations\NullController.cs" />
<Compile Include="Base Implementations\NullEmulator.cs" /> <Compile Include="Base Implementations\NullEmulator.cs" />
<Compile Include="Base Implementations\NullSound.cs" /> <Compile Include="Base Implementations\NullSound.cs" />
@ -72,6 +73,7 @@
<Compile Include="Interfaces\IEmulatorService.cs" /> <Compile Include="Interfaces\IEmulatorService.cs" />
<Compile Include="Interfaces\IInputCallbackSystem.cs" /> <Compile Include="Interfaces\IInputCallbackSystem.cs" />
<Compile Include="Interfaces\IInputPollable.cs" /> <Compile Include="Interfaces\IInputPollable.cs" />
<Compile Include="Interfaces\IMemoryCallbackSystem.cs" />
<Compile Include="Interfaces\IMemoryDomains.cs" /> <Compile Include="Interfaces\IMemoryDomains.cs" />
<Compile Include="Interfaces\ISaveRam.cs" /> <Compile Include="Interfaces\ISaveRam.cs" />
<Compile Include="Interfaces\IEmulatorServiceProvider.cs" /> <Compile Include="Interfaces\IEmulatorServiceProvider.cs" />

View File

@ -7,9 +7,13 @@ namespace BizHawk.Emulation.Common
{ {
public class CoreComm public class CoreComm
{ {
public ICoreFileProvider CoreFileProvider; public CoreComm(Action<string> ShowMessage, Action<string> NotifyMessage)
{
this.ShowMessage = ShowMessage;
this.Notify = NotifyMessage;
}
public MemoryCallbackSystem MemoryCallbackSystem = new MemoryCallbackSystem(); public ICoreFileProvider CoreFileProvider;
public double VsyncRate public double VsyncRate
{ {
@ -47,129 +51,8 @@ namespace BizHawk.Emulation.Common
/// </summary> /// </summary>
public Action<string> Notify { get; private set; } public Action<string> Notify { get; private set; }
public CoreComm(Action<string> ShowMessage, Action<string> NotifyMessage)
{
this.ShowMessage = ShowMessage;
this.Notify = NotifyMessage;
}
public Func<object> RequestGLContext; public Func<object> RequestGLContext;
public Action<object> ActivateGLContext; public Action<object> ActivateGLContext;
public Action DeactivateGLContext; //this shouldnt be necessary.. frontend should be changing context before it does anything.. but for now.. public Action DeactivateGLContext; //this shouldnt be necessary.. frontend should be changing context before it does anything.. but for now..
} }
public class MemoryCallbackSystem
{
private readonly List<Action> _reads = new List<Action>();
private readonly List<uint?> _readAddrs = new List<uint?>();
private readonly List<Action> _writes = new List<Action>();
private readonly List<uint?> _writeAddrs = new List<uint?>();
private readonly List<Action> _executes = new List<Action>();
private readonly List<uint> _execAddrs = new List<uint>();
public void AddRead(Action function, uint? addr)
{
_reads.Add(function);
_readAddrs.Add(addr);
}
public void AddWrite(Action function, uint? addr)
{
_writes.Add(function);
_writeAddrs.Add(addr);
}
public void AddExecute(Action function, uint addr)
{
_executes.Add(function);
_execAddrs.Add(addr);
}
public void CallRead(uint addr)
{
for (int i = 0; i < _reads.Count; i++)
{
if (!_readAddrs[i].HasValue || _readAddrs[i].Value == addr)
{
_reads[i]();
}
}
}
public void CallWrite(uint addr)
{
for (int i = 0; i < _writes.Count; i++)
{
if (!_writeAddrs[i].HasValue || _writeAddrs[i] == addr)
{
_writes[i]();
}
}
}
public void CallExecute(uint addr)
{
for (int i = 0; i < _executes.Count; i++)
{
if (_execAddrs[i] == addr)
{
_executes[i]();
}
}
}
public bool HasReads { get { return _reads.Any(); } }
public bool HasWrites { get { return _writes.Any(); } }
public bool HasExecutes { get { return _executes.Any(); } }
public void Remove(Action action)
{
for (int i = 0; i < _reads.Count; i++)
{
if (_reads[i] == action)
{
_reads.Remove(_reads[i]);
_readAddrs.Remove(_readAddrs[i]);
}
}
for (int i = 0; i < _writes.Count; i++)
{
if (_writes[i] == action)
{
_writes.Remove(_writes[i]);
_writeAddrs.Remove(_writeAddrs[i]);
}
}
for (int i = 0; i < _executes.Count; i++)
{
if (_executes[i] == action)
{
_executes.Remove(_executes[i]);
_execAddrs.Remove(_execAddrs[i]);
}
}
}
public void RemoveAll(IEnumerable<Action> actions)
{
foreach (var action in actions)
{
Remove(action);
}
}
public void Clear()
{
_reads.Clear();
_readAddrs.Clear();
_writes.Clear();
_writes.Clear();
_executes.Clear();
_execAddrs.Clear();
}
}
} }

View File

@ -77,26 +77,6 @@ namespace BizHawk.Emulation.Common.IEmulatorExtensions
return (IInputPollable)core.ServiceProvider.GetService<IInputPollable>(); return (IInputPollable)core.ServiceProvider.GetService<IInputPollable>();
} }
public static bool CpuTraceAvailable(this IEmulator core)
{
// TODO: this is a pretty ugly way to handle this
var debuggable = (IDebuggable)core.ServiceProvider.GetService<IDebuggable>();
if (debuggable != null)
{
try
{
var tracer = debuggable.Tracer;
return true;
}
catch(NotImplementedException)
{
return false;
}
}
return false;
}
public static bool CanDebug(this IEmulator core) public static bool CanDebug(this IEmulator core)
{ {
if (core == null) if (core == null)
@ -112,6 +92,56 @@ namespace BizHawk.Emulation.Common.IEmulatorExtensions
return (IDebuggable)core.ServiceProvider.GetService<IDebuggable>(); return (IDebuggable)core.ServiceProvider.GetService<IDebuggable>();
} }
public static bool CpuTraceAvailable(this IEmulator core)
{
if (core == null)
{
return false;
}
// TODO: this is a pretty ugly way to handle this
var debuggable = (IDebuggable)core.ServiceProvider.GetService<IDebuggable>();
if (debuggable != null)
{
try
{
var tracer = debuggable.Tracer;
return true;
}
catch (NotImplementedException)
{
return false;
}
}
return false;
}
public static bool MemoryCallbacksAvailable(this IEmulator core)
{
if (core == null)
{
return false;
}
// TODO: this is a pretty ugly way to handle this
var debuggable = (IDebuggable)core.ServiceProvider.GetService<IDebuggable>();
if (debuggable != null)
{
try
{
var tracer = debuggable.MemoryCallbacks;
return true;
}
catch (NotImplementedException)
{
return false;
}
}
return false;
}
// TODO: a better place for these // TODO: a better place for these
public static bool IsImplemented(this MethodInfo info) public static bool IsImplemented(this MethodInfo info)
{ {

View File

@ -18,5 +18,7 @@ namespace BizHawk.Emulation.Common
void SetCpuRegister(string register, int value); void SetCpuRegister(string register, int value);
ITracer Tracer { get; } ITracer Tracer { get; }
IMemoryCallbackSystem MemoryCallbacks { get; }
} }
} }

View File

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
namespace BizHawk.Emulation.Common
{
public interface IMemoryCallbackSystem
{
/// <summary>
/// Returns whether or not there are currently any read hooks
/// </summary>
bool HasReads { get; }
/// <summary>
/// Returns whether or not there are currently any write hooks
/// </summary>
bool HasWrites { get; }
/// <summary>
/// Returns whether or not there are currently any execute hooks
/// </summary>
bool HasExecutes { get; }
/// <summary>
/// Adds a Read callback for the given address
/// If no address is specified the callback will be hooked to all addresses
/// </summary>
void AddRead(Action function, uint? addr);
/// <summary>
/// Adds a Write callback for the given address
/// If no address is specified the callback will be hooked to all addresses
/// </summary>
void AddWrite(Action function, uint? addr);
/// <summary>
/// Adds an Execute callback for the given address
/// </summary>
void AddExecute(Action function, uint addr);
/// <summary>
/// Executes all Read callbacks for the given addr
/// </summary>
void CallRead(uint addr);
/// <summary>
/// Executes all Write callbacks for the given addr
/// </summary>
void CallWrite(uint addr);
/// <summary>
/// Executes all Execute callbacks for the given addr
/// </summary>
void CallExecute(uint addr);
/// <summary>
/// Removes the given callback from the list
/// </summary>
void Remove(Action action);
/// <summary>
/// Removes the given callbacks from the list
/// </summary>
void RemoveAll(IEnumerable<Action> actions);
/// <summary>
/// Removes all read,write, and execute callbacks
/// </summary>
void Clear();
}
}

View File

@ -59,7 +59,7 @@ namespace BizHawk.Emulation.Cores.Components.H6280
LagIFlag = FlagI; LagIFlag = FlagI;
if (Debug) Logger(State()); if (Debug) Logger(State());
CoreComm.MemoryCallbackSystem.CallExecute(PC); Core.MemoryCallbacks.CallExecute(PC);
if (CDLLoggingActive) CDLOpcode(); if (CDLLoggingActive) CDLOpcode();
byte opcode = ReadMemory(PC++); byte opcode = ReadMemory(PC++);

View File

@ -9,10 +9,10 @@ namespace BizHawk.Emulation.Cores.Components.H6280
{ {
public sealed partial class HuC6280 public sealed partial class HuC6280
{ {
public HuC6280(CoreComm comm) public HuC6280(IDebuggable core)
{ {
Reset(); Reset();
CoreComm = comm; Core = core;
} }
public void Reset() public void Reset()
@ -224,7 +224,7 @@ namespace BizHawk.Emulation.Cores.Components.H6280
public Action<int, byte> WriteVDC; public Action<int, byte> WriteVDC;
public Action<int> ThinkAction = delegate { }; public Action<int> ThinkAction = delegate { };
public CoreComm CoreComm; public IDebuggable Core;
public byte ReadMemory(ushort address) public byte ReadMemory(ushort address)
{ {

View File

@ -125,5 +125,7 @@ namespace BizHawk.Emulation.Cores.Calculators
[FeatureNotImplemented] [FeatureNotImplemented]
get { throw new NotImplementedException(); } get { throw new NotImplementedException(); }
} }
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
} }
} }

View File

@ -54,6 +54,7 @@ namespace BizHawk.Emulation.Cores.Calculators
{ {
ServiceProvider = new BasicServiceProvider(this); ServiceProvider = new BasicServiceProvider(this);
InputCallbacks = new InputCallbackSystem(); InputCallbacks = new InputCallbackSystem();
MemoryCallbacks = new MemoryCallbackSystem();
PutSettings((TI83Settings)Settings ?? new TI83Settings()); PutSettings((TI83Settings)Settings ?? new TI83Settings());
CoreComm = comm; CoreComm = comm;
@ -93,7 +94,7 @@ namespace BizHawk.Emulation.Cores.Calculators
ret = rom[romPage * 0x4000 + addr - 0x4000]; //other rom page ret = rom[romPage * 0x4000 + addr - 0x4000]; //other rom page
else ret = ram[addr - 0x8000]; else ret = ram[addr - 0x8000];
CoreComm.MemoryCallbackSystem.CallRead(addr); MemoryCallbacks.CallRead(addr);
return ret; return ret;
} }
@ -106,7 +107,7 @@ namespace BizHawk.Emulation.Cores.Calculators
return; //other rom page return; //other rom page
else ram[addr - 0x8000] = value; else ram[addr - 0x8000] = value;
CoreComm.MemoryCallbackSystem.CallWrite(addr); MemoryCallbacks.CallWrite(addr);
} }
public void WriteHardware(ushort addr, byte value) public void WriteHardware(ushort addr, byte value)

View File

@ -132,6 +132,12 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
[FeatureNotImplemented] [FeatureNotImplemented]
get { throw new NotImplementedException(); } get { throw new NotImplementedException(); }
} }
public IMemoryCallbackSystem MemoryCallbacks
{
[FeatureNotImplemented]
get { throw new NotImplementedException(); }
}
} }
static public class C64Util static public class C64Util

View File

@ -108,7 +108,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_mapper.Bit13 = addr.Bit(13); _mapper.Bit13 = addr.Bit(13);
var temp = _mapper.ReadMemory((ushort)(addr & 0x1FFF)); var temp = _mapper.ReadMemory((ushort)(addr & 0x1FFF));
CoreComm.MemoryCallbackSystem.CallRead(addr); MemoryCallbacks.CallRead(addr);
return temp; return temp;
} }
@ -130,7 +130,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_mapper.WriteMemory((ushort)(addr & 0x1FFF), value); _mapper.WriteMemory((ushort)(addr & 0x1FFF), value);
CoreComm.MemoryCallbackSystem.CallWrite(addr); MemoryCallbacks.CallWrite(addr);
} }
public void PokeMemory(ushort addr, byte value) public void PokeMemory(ushort addr, byte value)
@ -140,7 +140,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public void ExecFetch(ushort addr) public void ExecFetch(ushort addr)
{ {
CoreComm.MemoryCallbackSystem.CallExecute(addr); MemoryCallbacks.CallExecute(addr);
} }
private static MapperBase SetMultiCartMapper(int romLength, int gameTotal) private static MapperBase SetMultiCartMapper(int romLength, int gameTotal)

View File

@ -57,5 +57,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
} }
public ITracer Tracer { get; private set; } public ITracer Tracer { get; private set; }
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
} }
} }

View File

@ -24,9 +24,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
[CoreConstructor("A26")] [CoreConstructor("A26")]
public Atari2600(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings) public Atari2600(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
{ {
Tracer = new TraceBuffer();
ServiceProvider = new BasicServiceProvider(this); ServiceProvider = new BasicServiceProvider(this);
Tracer = new TraceBuffer();
MemoryCallbacks = new MemoryCallbackSystem();
InputCallbacks = new InputCallbackSystem(); InputCallbacks = new InputCallbackSystem();
Ram = new byte[128]; Ram = new byte[128];
CoreComm = comm; CoreComm = comm;
Settings = (A2600Settings)settings ?? new A2600Settings(); Settings = (A2600Settings)settings ?? new A2600Settings();

View File

@ -59,5 +59,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
[FeatureNotImplemented] [FeatureNotImplemented]
get { throw new NotImplementedException(); } get { throw new NotImplementedException(); }
} }
public IMemoryCallbackSystem MemoryCallbacks
{
[FeatureNotImplemented]
get { throw new NotImplementedException(); }
}
} }
} }

View File

@ -72,6 +72,12 @@ namespace BizHawk.Emulation.Cores.ColecoVision
get { throw new NotImplementedException(); } get { throw new NotImplementedException(); }
} }
public IMemoryCallbackSystem MemoryCallbacks
{
[FeatureNotImplemented]
get { throw new NotImplementedException(); }
}
public MemoryDomainList MemoryDomains { get { return memoryDomains; } } public MemoryDomainList MemoryDomains { get { return memoryDomains; } }
MemoryDomainList memoryDomains; MemoryDomainList memoryDomains;
const ushort RamSizeMask = 0x03FF; const ushort RamSizeMask = 0x03FF;

View File

@ -164,8 +164,6 @@
} }
} }
CoreComm.MemoryCallbackSystem.CallRead(addr);
if (cart != null) if (cart != null)
{ {
return (ushort)cart; return (ushort)cart;
@ -356,8 +354,6 @@
} }
} }
CoreComm.MemoryCallbackSystem.CallWrite(addr);
return (cart || stic || psg); return (cart || stic || psg);
} }
} }

View File

@ -32,6 +32,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
throw new NotImplementedException(); throw new NotImplementedException();
} }
public IMemoryCallbackSystem MemoryCallbacks
{
[FeatureNotImplemented]
get { throw new NotImplementedException(); }
}
public static readonly ControllerDefinition GBAController = public static readonly ControllerDefinition GBAController =
new ControllerDefinition new ControllerDefinition
{ {

View File

@ -24,6 +24,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
{ {
ServiceProvider = new BasicServiceProvider(this); ServiceProvider = new BasicServiceProvider(this);
CoreComm = comm; CoreComm = comm;
MemoryCallbacks = new MemoryCallbackSystem();
byte[] biosfile = CoreComm.CoreFileProvider.GetFirmware("GBA", "Bios", true, "GBA bios file is mandatory."); byte[] biosfile = CoreComm.CoreFileProvider.GetFirmware("GBA", "Bios", true, "GBA bios file is mandatory.");
if (file.Length > 32 * 1024 * 1024) if (file.Length > 32 * 1024 * 1024)
throw new ArgumentException("ROM is too big to be a GBA ROM!"); throw new ArgumentException("ROM is too big to be a GBA ROM!");
@ -119,6 +121,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
public ITracer Tracer { get; private set; } public ITracer Tracer { get; private set; }
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
public string SystemId { get { return "GBA"; } } public string SystemId { get { return "GBA"; } }
public bool DeterministicEmulation { get; private set; } public bool DeterministicEmulation { get; private set; }
@ -283,9 +287,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
void InitCallbacks() void InitCallbacks()
{ {
padcb = new LibVBANext.StandardCallback(() => InputCallbacks.Call()); padcb = new LibVBANext.StandardCallback(() => InputCallbacks.Call());
fetchcb = new LibVBANext.AddressCallback((addr) => CoreComm.MemoryCallbackSystem.CallExecute(addr)); fetchcb = new LibVBANext.AddressCallback((addr) => MemoryCallbacks.CallExecute(addr));
readcb = new LibVBANext.AddressCallback((addr) => CoreComm.MemoryCallbackSystem.CallRead(addr)); readcb = new LibVBANext.AddressCallback((addr) => MemoryCallbacks.CallRead(addr));
writecb = new LibVBANext.AddressCallback((addr) => CoreComm.MemoryCallbackSystem.CallWrite(addr)); writecb = new LibVBANext.AddressCallback((addr) => MemoryCallbacks.CallWrite(addr));
tracecb = new LibVBANext.TraceCallback((addr, opcode) => Tracer.Put(Trace(addr, opcode))); tracecb = new LibVBANext.TraceCallback((addr, opcode) => Tracer.Put(Trace(addr, opcode)));
_inputCallbacks.ActiveChanged += SyncPadCallback; _inputCallbacks.ActiveChanged += SyncPadCallback;
} }
@ -304,9 +308,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
void SyncCallbacks() void SyncCallbacks()
{ {
//LibVBANext.SetPadCallback(Core, InputCallbacks.Any() ? padcb : null); //LibVBANext.SetPadCallback(Core, InputCallbacks.Any() ? padcb : null);
LibVBANext.SetFetchCallback(Core, CoreComm.MemoryCallbackSystem.HasExecutes ? fetchcb : null); LibVBANext.SetFetchCallback(Core, MemoryCallbacks.HasExecutes ? fetchcb : null);
LibVBANext.SetReadCallback(Core, CoreComm.MemoryCallbackSystem.HasReads ? readcb : null); LibVBANext.SetReadCallback(Core, MemoryCallbacks.HasReads ? readcb : null);
LibVBANext.SetWriteCallback(Core, CoreComm.MemoryCallbackSystem.HasWrites ? writecb : null); LibVBANext.SetWriteCallback(Core, MemoryCallbacks.HasWrites ? writecb : null);
LibVBANext.SetTraceCallback(Core, Tracer.Enabled ? tracecb : null); LibVBANext.SetTraceCallback(Core, Tracer.Enabled ? tracecb : null);
} }

View File

@ -140,6 +140,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{ {
ServiceProvider = new BasicServiceProvider(this); ServiceProvider = new BasicServiceProvider(this);
Tracer = new TraceBuffer(); Tracer = new TraceBuffer();
MemoryCallbacks = new MemoryCallbackSystem();
CoreComm = comm; CoreComm = comm;
comm.VsyncNum = 262144; comm.VsyncNum = 262144;
@ -276,6 +277,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
public ITracer Tracer { get; private set; } public ITracer Tracer { get; private set; }
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
/// <summary> /// <summary>
/// true if the emulator is currently emulating CGB /// true if the emulator is currently emulating CGB
/// </summary> /// </summary>
@ -643,7 +646,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
void RefreshMemoryCallbacks() void RefreshMemoryCallbacks()
{ {
var mcs = CoreComm.MemoryCallbackSystem; var mcs = MemoryCallbacks;
// we RefreshMemoryCallbacks() after the triggers in case the trigger turns itself off at that point // we RefreshMemoryCallbacks() after the triggers in case the trigger turns itself off at that point

View File

@ -93,6 +93,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
get { throw new NotImplementedException(); } get { throw new NotImplementedException(); }
} }
public IMemoryCallbackSystem MemoryCallbacks
{
[FeatureNotImplemented]
get { throw new NotImplementedException(); }
}
public IVideoProvider VideoProvider { get { return this; } } public IVideoProvider VideoProvider { get { return this; } }
public ISoundProvider SoundProvider { get { return null; } } public ISoundProvider SoundProvider { get { return null; } }
public ISyncSoundProvider SyncSoundProvider { get { return this; } } public ISyncSoundProvider SyncSoundProvider { get { return this; } }

View File

@ -67,5 +67,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
} }
} }

View File

@ -52,6 +52,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
public N64(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings) public N64(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings)
{ {
ServiceProvider = new BasicServiceProvider(this); ServiceProvider = new BasicServiceProvider(this);
MemoryCallbacks = new MemoryCallbackSystem();
int SaveType = 0; int SaveType = 0;
if (game.OptionValue("SaveType") == "EEPROM_16K") if (game.OptionValue("SaveType") == "EEPROM_16K")
@ -399,7 +400,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
private void RefreshMemoryCallbacks() private void RefreshMemoryCallbacks()
{ {
var mcs = CoreComm.MemoryCallbackSystem; var mcs = MemoryCallbacks;
// we RefreshMemoryCallbacks() after the triggers in case the trigger turns itself off at that point // we RefreshMemoryCallbacks() after the triggers in case the trigger turns itself off at that point
if (mcs.HasReads) if (mcs.HasReads)

View File

@ -534,7 +534,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public void ExecFetch(ushort addr) public void ExecFetch(ushort addr)
{ {
CoreComm.MemoryCallbackSystem.CallExecute(addr); MemoryCallbacks.CallExecute(addr);
} }
public byte ReadMemory(ushort addr) public byte ReadMemory(ushort addr)
@ -579,7 +579,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
ret = sysbus_watch[addr].ApplyGameGenie(ret); ret = sysbus_watch[addr].ApplyGameGenie(ret);
} }
CoreComm.MemoryCallbackSystem.CallRead(addr); MemoryCallbacks.CallRead(addr);
DB = ret; DB = ret;
@ -633,7 +633,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
board.WritePRG(addr - 0x8000, value); board.WritePRG(addr - 0x8000, value);
} }
CoreComm.MemoryCallbackSystem.CallWrite(addr); MemoryCallbacks.CallWrite(addr);
} }
} }

View File

@ -40,6 +40,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
this.ControllerSettings = this.SyncSettings.Controls; this.ControllerSettings = this.SyncSettings.Controls;
CoreComm = comm; CoreComm = comm;
Tracer = new TraceBuffer(); Tracer = new TraceBuffer();
MemoryCallbacks = new MemoryCallbackSystem();
BootGodDB.Initialize(); BootGodDB.Initialize();
videoProvider = new MyVideoProvider(this); videoProvider = new MyVideoProvider(this);
Init(game, rom, fdsbios); Init(game, rom, fdsbios);
@ -926,6 +927,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
} }
public ITracer Tracer { get; private set; } public ITracer Tracer { get; private set; }
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
NESSettings Settings = new NESSettings(); NESSettings Settings = new NESSettings();
NESSyncSettings SyncSettings = new NESSyncSettings(); NESSyncSettings SyncSettings = new NESSyncSettings();

View File

@ -402,6 +402,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
} }
} }
public IMemoryCallbackSystem MemoryCallbacks
{
[FeatureNotImplemented]
get { throw new NotImplementedException(); }
}
#endregion #endregion
public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { throw new NotImplementedException(); } } public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { throw new NotImplementedException(); } }

View File

@ -35,6 +35,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
public LibsnesCore(GameInfo game, byte[] romData, bool deterministicEmulation, byte[] xmlData, CoreComm comm, object Settings, object SyncSettings) public LibsnesCore(GameInfo game, byte[] romData, bool deterministicEmulation, byte[] xmlData, CoreComm comm, object Settings, object SyncSettings)
{ {
ServiceProvider = new BasicServiceProvider(this); ServiceProvider = new BasicServiceProvider(this);
MemoryCallbacks = new MemoryCallbackSystem();
Tracer = new TraceBuffer();
_game = game; _game = game;
CoreComm = comm; CoreComm = comm;
byte[] sgbRomData = null; byte[] sgbRomData = null;
@ -146,8 +149,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
CoreComm.VsyncDen = 4 * 341 * 312; CoreComm.VsyncDen = 4 * 341 * 312;
} }
Tracer = new TraceBuffer();
api.CMD_power(); api.CMD_power();
SetupMemoryDomains(romData, sgbRomData); SetupMemoryDomains(romData, sgbRomData);
@ -250,6 +251,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } } public IInputCallbackSystem InputCallbacks { [FeatureNotImplemented]get { return _inputCallbacks; } }
public ITracer Tracer { get; private set; } public ITracer Tracer { get; private set; }
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
[FeatureNotImplemented] [FeatureNotImplemented]
public void SetCpuRegister(string register, int value) public void SetCpuRegister(string register, int value)
@ -385,7 +387,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
void ReadHook(uint addr) void ReadHook(uint addr)
{ {
CoreComm.MemoryCallbackSystem.CallRead(addr); MemoryCallbacks.CallRead(addr);
//we RefreshMemoryCallbacks() after the trigger in case the trigger turns itself off at that point //we RefreshMemoryCallbacks() after the trigger in case the trigger turns itself off at that point
//EDIT: for now, theres some IPC re-entrancy problem //EDIT: for now, theres some IPC re-entrancy problem
//RefreshMemoryCallbacks(); //RefreshMemoryCallbacks();
@ -393,7 +395,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
} }
void ExecHook(uint addr) void ExecHook(uint addr)
{ {
CoreComm.MemoryCallbackSystem.CallExecute(addr); MemoryCallbacks.CallExecute(addr);
//we RefreshMemoryCallbacks() after the trigger in case the trigger turns itself off at that point //we RefreshMemoryCallbacks() after the trigger in case the trigger turns itself off at that point
//EDIT: for now, theres some IPC re-entrancy problem //EDIT: for now, theres some IPC re-entrancy problem
//RefreshMemoryCallbacks(); //RefreshMemoryCallbacks();
@ -401,7 +403,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
} }
void WriteHook(uint addr, byte val) void WriteHook(uint addr, byte val)
{ {
CoreComm.MemoryCallbackSystem.CallWrite(addr); MemoryCallbacks.CallWrite(addr);
//we RefreshMemoryCallbacks() after the trigger in case the trigger turns itself off at that point //we RefreshMemoryCallbacks() after the trigger in case the trigger turns itself off at that point
//EDIT: for now, theres some IPC re-entrancy problem //EDIT: for now, theres some IPC re-entrancy problem
//RefreshMemoryCallbacks(); //RefreshMemoryCallbacks();
@ -649,7 +651,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
void RefreshMemoryCallbacks(bool suppress) void RefreshMemoryCallbacks(bool suppress)
{ {
var mcs = CoreComm.MemoryCallbackSystem; var mcs = MemoryCallbacks;
api.QUERY_set_state_hook_exec(!suppress && mcs.HasExecutes); api.QUERY_set_state_hook_exec(!suppress && mcs.HasExecutes);
api.QUERY_set_state_hook_read(!suppress && mcs.HasReads); api.QUERY_set_state_hook_read(!suppress && mcs.HasReads);
api.QUERY_set_state_hook_write(!suppress && mcs.HasWrites); api.QUERY_set_state_hook_write(!suppress && mcs.HasWrites);

View File

@ -70,6 +70,7 @@ namespace BizHawk.Emulation.Cores.PCEngine
{ {
ServiceProvider = new BasicServiceProvider(this); ServiceProvider = new BasicServiceProvider(this);
Tracer = new TraceBuffer(); Tracer = new TraceBuffer();
MemoryCallbacks = new MemoryCallbackSystem();
CoreComm = comm; CoreComm = comm;
switch (game.System) switch (game.System)
@ -94,11 +95,13 @@ namespace BizHawk.Emulation.Cores.PCEngine
public string BoardName { get { return null; } } public string BoardName { get { return null; } }
public ITracer Tracer { get; private set; } public ITracer Tracer { get; private set; }
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
public PCEngine(CoreComm comm, GameInfo game, Disc disc, object Settings, object syncSettings) public PCEngine(CoreComm comm, GameInfo game, Disc disc, object Settings, object syncSettings)
{ {
CoreComm = comm; CoreComm = comm;
Tracer = new TraceBuffer(); Tracer = new TraceBuffer();
MemoryCallbacks = new MemoryCallbackSystem();
CoreComm.UsesDriveLed = true; CoreComm.UsesDriveLed = true;
systemid = "PCECD"; systemid = "PCECD";
Type = NecSystemType.TurboCD; Type = NecSystemType.TurboCD;
@ -152,7 +155,7 @@ namespace BizHawk.Emulation.Cores.PCEngine
void Init(GameInfo game, byte[] rom) void Init(GameInfo game, byte[] rom)
{ {
Controller = NullController.GetNullController(); Controller = NullController.GetNullController();
Cpu = new HuC6280(CoreComm); Cpu = new HuC6280(this);
VCE = new VCE(); VCE = new VCE();
VDC1 = new VDC(this, Cpu, VCE); VDC1 = new VDC(this, Cpu, VCE);
PSG = new HuC6280PSG(); PSG = new HuC6280PSG();

View File

@ -48,6 +48,12 @@ namespace BizHawk.Emulation.Cores.Sega.Genesis
[FeatureNotImplemented] [FeatureNotImplemented]
public IInputCallbackSystem InputCallbacks { get { throw new NotImplementedException(); } } public IInputCallbackSystem InputCallbacks { get { throw new NotImplementedException(); } }
public IMemoryCallbackSystem MemoryCallbacks
{
[FeatureNotImplemented]
get { throw new NotImplementedException(); }
}
public void ResetCounters() public void ResetCounters()
{ {
Frame = 0; Frame = 0;

View File

@ -16,7 +16,7 @@
else else
ret = SystemRam[address & RamSizeMask]; ret = SystemRam[address & RamSizeMask];
CoreComm.MemoryCallbackSystem.CallRead(address); MemoryCallbacks.CallRead(address);
return ret; return ret;
} }
@ -27,7 +27,7 @@
else if (address >= 0xC000) else if (address >= 0xC000)
SystemRam[address & RamSizeMask] = value; SystemRam[address & RamSizeMask] = value;
CoreComm.MemoryCallbackSystem.CallWrite((uint)address); MemoryCallbacks.CallWrite((uint)address);
} }
void InitExt2kMapper(int size) void InitExt2kMapper(int size)

View File

@ -53,7 +53,7 @@
ret = SystemRam[address & RamSizeMask]; ret = SystemRam[address & RamSizeMask];
} }
CoreComm.MemoryCallbackSystem.CallRead(address); MemoryCallbacks.CallRead(address);
return ret; return ret;
} }
@ -91,7 +91,7 @@
else if (address == 0xFFFF) RomBank2 = (byte)(value % RomBanks); else if (address == 0xFFFF) RomBank2 = (byte)(value % RomBanks);
return; return;
} }
CoreComm.MemoryCallbackSystem.CallWrite((uint)address); MemoryCallbacks.CallWrite((uint)address);
} }
void InitSegaMapper() void InitSegaMapper()

View File

@ -81,6 +81,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem(); private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem();
public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } } public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } }
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
byte Port01 = 0xFF; byte Port01 = 0xFF;
byte Port02 = 0xFF; byte Port02 = 0xFF;
@ -100,6 +101,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
Settings = (SMSSettings)settings ?? new SMSSettings(); Settings = (SMSSettings)settings ?? new SMSSettings();
SyncSettings = (SMSSyncSettings)syncSettings ?? new SMSSyncSettings(); SyncSettings = (SMSSyncSettings)syncSettings ?? new SMSSyncSettings();
CoreComm = comm; CoreComm = comm;
MemoryCallbacks = new MemoryCallbackSystem();
IsGameGear = game.System == "GG"; IsGameGear = game.System == "GG";
IsSG1000 = game.System == "SG"; IsSG1000 = game.System == "SG";

View File

@ -397,6 +397,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
} }
} }
private readonly MemoryCallbackSystem _memoryCallbacks = new MemoryCallbackSystem();
public IMemoryCallbackSystem MemoryCallbacks { get { return _memoryCallbacks; } }
#endregion #endregion
// TODO: use render and rendersound // TODO: use render and rendersound
@ -660,17 +663,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
void InitMemCallbacks() void InitMemCallbacks()
{ {
ExecCallback = new LibGPGX.mem_cb(a => CoreComm.MemoryCallbackSystem.CallExecute(a)); ExecCallback = new LibGPGX.mem_cb(a => MemoryCallbacks.CallExecute(a));
ReadCallback = new LibGPGX.mem_cb(a => CoreComm.MemoryCallbackSystem.CallRead(a)); ReadCallback = new LibGPGX.mem_cb(a => MemoryCallbacks.CallRead(a));
WriteCallback = new LibGPGX.mem_cb(a => CoreComm.MemoryCallbackSystem.CallWrite(a)); WriteCallback = new LibGPGX.mem_cb(a => MemoryCallbacks.CallWrite(a));
} }
void RefreshMemCallbacks() void RefreshMemCallbacks()
{ {
LibGPGX.gpgx_set_mem_callback( LibGPGX.gpgx_set_mem_callback(
CoreComm.MemoryCallbackSystem.HasReads ? ReadCallback : null, MemoryCallbacks.HasReads ? ReadCallback : null,
CoreComm.MemoryCallbackSystem.HasWrites ? WriteCallback : null, MemoryCallbacks.HasWrites ? WriteCallback : null,
CoreComm.MemoryCallbackSystem.HasExecutes ? ExecCallback : null); MemoryCallbacks.HasExecutes ? ExecCallback : null);
} }
void KillMemCallbacks() void KillMemCallbacks()

View File

@ -90,6 +90,7 @@ namespace BizHawk.Emulation.Cores.WonderSwan
public WonderSwan(CoreComm comm, byte[] file, bool deterministic, object Settings, object SyncSettings) public WonderSwan(CoreComm comm, byte[] file, bool deterministic, object Settings, object SyncSettings)
{ {
ServiceProvider = new BasicServiceProvider(this); ServiceProvider = new BasicServiceProvider(this);
MemoryCallbacks = new MemoryCallbackSystem();
CoreComm = comm; CoreComm = comm;
_Settings = (Settings)Settings ?? new Settings(); _Settings = (Settings)Settings ?? new Settings();
_SyncSettings = (SyncSettings)SyncSettings ?? new SyncSettings(); _SyncSettings = (SyncSettings)SyncSettings ?? new SyncSettings();
@ -141,6 +142,8 @@ namespace BizHawk.Emulation.Cores.WonderSwan
} }
} }
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
public void Dispose() public void Dispose()
{ {
if (Core != IntPtr.Zero) if (Core != IntPtr.Zero)
@ -353,15 +356,15 @@ namespace BizHawk.Emulation.Cores.WonderSwan
void ReadCallback(uint addr) void ReadCallback(uint addr)
{ {
CoreComm.MemoryCallbackSystem.CallRead(addr); MemoryCallbacks.CallRead(addr);
} }
void WriteCallback(uint addr) void WriteCallback(uint addr)
{ {
CoreComm.MemoryCallbackSystem.CallWrite(addr); MemoryCallbacks.CallWrite(addr);
} }
void ExecCallback(uint addr) void ExecCallback(uint addr)
{ {
CoreComm.MemoryCallbackSystem.CallExecute(addr); MemoryCallbacks.CallExecute(addr);
} }
void ButtonCallback() void ButtonCallback()
{ {
@ -391,9 +394,9 @@ namespace BizHawk.Emulation.Cores.WonderSwan
void SetMemoryCallbacks() void SetMemoryCallbacks()
{ {
BizSwan.bizswan_setmemorycallbacks(Core, BizSwan.bizswan_setmemorycallbacks(Core,
CoreComm.MemoryCallbackSystem.HasReads ? ReadCallbackD : null, MemoryCallbacks.HasReads ? ReadCallbackD : null,
CoreComm.MemoryCallbackSystem.HasWrites ? WriteCallbackD : null, MemoryCallbacks.HasWrites ? WriteCallbackD : null,
CoreComm.MemoryCallbackSystem.HasExecutes ? ExecCallbackD : null); MemoryCallbacks.HasExecutes ? ExecCallbackD : null);
} }
#endregion #endregion