diff --git a/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs b/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs index c449a14bd0..48fa33ae8e 100644 --- a/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs +++ b/BizHawk.Client.Common/lua/EmuLuaLibrary.Events.cs @@ -159,78 +159,21 @@ namespace BizHawk.Client.Common return nlf.GUID.ToString(); } - public void event_onmemoryread(LuaFunction luaf, object address = null) + public string event_onmemoryread(LuaFunction luaf, object address = null, string name = null) { - //TODO: allow a list of addresses - if (luaf != null) - { - int? _addr; - if (address == null) - { - _addr = null; - } - else - { - _addr = LuaInt(address); - } - - Global.Emulator.CoreComm.MemoryCallbackSystem.ReadAddr = _addr; - Global.Emulator.CoreComm.MemoryCallbackSystem.SetReadCallback(delegate(uint addr) - { - try - { - luaf.Call(addr); - } - catch (SystemException e) - { - LogOutputCallback( - "error running function attached by lua function event.onmemoryread" + - "\nError message: " + - e.Message); - } - }); - } - else - { - Global.Emulator.CoreComm.MemoryCallbackSystem.SetReadCallback(null); - } + NamedLuaFunction nlf = new NamedLuaFunction(luaf, "OnMemoryRead", LogOutputCallback, name); + _luaFunctions.Add(nlf); + Global.CoreComm.MemoryCallbackSystem.AddRead(nlf.Callback, (address != null ? LuaUInt(address) : (uint?)null)); + return nlf.GUID.ToString(); + } - public void event_onmemorywrite(LuaFunction luaf, object address = null) + public string event_onmemorywrite(LuaFunction luaf, object address = null, string name = null) { - //TODO: allow a list of addresses - if (luaf != null) - { - int? _addr; - if (address == null) - { - _addr = null; - } - else - { - _addr = LuaInt(address); - } - - Global.Emulator.CoreComm.MemoryCallbackSystem.WriteAddr = _addr; - Global.Emulator.CoreComm.MemoryCallbackSystem.SetWriteCallback(delegate(uint addr) - { - try - { - luaf.Call(addr); - } - catch (SystemException e) - { - LogOutputCallback( - "error running function attached by lua function event.onmemoryread" + - "\nError message: " + - e.Message); - } - }); - } - else - { - Global.Emulator.CoreComm.MemoryCallbackSystem.SetWriteCallback(null); - } + NamedLuaFunction nlf = new NamedLuaFunction(luaf, "OnMemoryWrite", LogOutputCallback, name); + _luaFunctions.Add(nlf); + Global.CoreComm.MemoryCallbackSystem.AddWrite(nlf.Callback, (address != null ? LuaUInt(address) : (uint?)null)); + return nlf.GUID.ToString(); } public string event_onsavestate(LuaFunction luaf, string name = null) diff --git a/BizHawk.Emulation.Common/Interfaces/CoreComms.cs b/BizHawk.Emulation.Common/Interfaces/CoreComms.cs index ebad19fb10..dcc34e6c3e 100644 --- a/BizHawk.Emulation.Common/Interfaces/CoreComms.cs +++ b/BizHawk.Emulation.Common/Interfaces/CoreComms.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Linq; +using System.Reflection; using System.Text; namespace BizHawk.Emulation.Common @@ -149,70 +151,76 @@ namespace BizHawk.Emulation.Common public class MemoryCallbackSystem { - public int? ReadAddr = null; - private Action ReadCallback; - public void SetReadCallback(Action func) + private List _reads = new List(); + private List _readAddrs = new List(); + + private List _writes = new List(); + private List _writeAddrs = new List(); + + public void AddRead(Action function, uint? addr) { - ReadCallback = func; + _reads.Add(function); + _readAddrs.Add(addr); } - public bool HasRead + public void AddWrite(Action function, uint? addr) { - get - { - return ReadCallback != null; - } + _writes.Add(function); + _writeAddrs.Add(addr); } - public void TriggerRead(int addr) + public void CallRead(uint addr) { - if (ReadCallback != null) + for (int i = 0; i < _reads.Count; i++) { - if (ReadAddr != null) + if (!_readAddrs[i].HasValue || _readAddrs[i].Value == addr) { - if (ReadAddr == addr) - { - ReadCallback((uint)addr); - } - } - else - { - ReadCallback((uint)addr); + _reads[i](); } } } - public int? WriteAddr = null; - private Action WriteCallback; - public void SetWriteCallback(Action func) + public void CallWrite(uint addr) { - WriteCallback = func; - } - - public bool HasWrite - { - get + for (int i = 0; i < _writes.Count; i++) { - return WriteCallback != null; + if (_writeAddrs[i] == addr) + { + _writes[i](); + } } } - public void TriggerWrite(int addr) + public bool HasReads { get { return _reads.Any(); } } + public bool HasWrites { get { return _writes.Any(); } } + + public void Remove(Action action) { - if (WriteCallback != null) + for (int i = 0; i < _reads.Count; i++) { - if (WriteAddr != null) + if (_reads[i] == action) { - if (WriteAddr == addr) - { - WriteCallback((uint)addr); - } - } - else - { - WriteCallback((uint)addr); + _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]); + } + } + } + + public void Clear() + { + _reads.Clear(); + _readAddrs.Clear(); + _writes.Clear(); + _writes.Clear(); } } } diff --git a/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.Core.cs b/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.Core.cs index 88441740a1..1640bf60a7 100644 --- a/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.Core.cs +++ b/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.Core.cs @@ -113,10 +113,7 @@ namespace BizHawk { byte temp = mapper.ReadMemory((ushort)(addr&0x1FFF)); - if (CoreComm.MemoryCallbackSystem.HasRead) - { - CoreComm.MemoryCallbackSystem.TriggerRead(addr); - } + CoreComm.MemoryCallbackSystem.CallRead(addr); return temp; } @@ -132,10 +129,7 @@ namespace BizHawk { mapper.WriteMemory((ushort)(addr & 0x1FFF), value); - if (CoreComm.MemoryCallbackSystem.HasWrite) - { - CoreComm.MemoryCallbackSystem.TriggerWrite(addr); - } + CoreComm.MemoryCallbackSystem.CallWrite((uint)addr); } public void HardReset() diff --git a/BizHawk.Emulation/Consoles/Calculator/TI83.cs b/BizHawk.Emulation/Consoles/Calculator/TI83.cs index 694284f8db..33d090d0ee 100644 --- a/BizHawk.Emulation/Consoles/Calculator/TI83.cs +++ b/BizHawk.Emulation/Consoles/Calculator/TI83.cs @@ -52,10 +52,7 @@ namespace BizHawk.Emulation.Consoles.Calculator ret = rom[romPage * 0x4000 + addr - 0x4000]; //other rom page else ret = ram[addr - 0x8000]; - if (CoreComm.MemoryCallbackSystem.HasRead) - { - CoreComm.MemoryCallbackSystem.TriggerRead(addr); - } + CoreComm.MemoryCallbackSystem.CallRead(addr); return ret; } @@ -68,10 +65,7 @@ namespace BizHawk.Emulation.Consoles.Calculator return; //other rom page else ram[addr - 0x8000] = value; - if (CoreComm.MemoryCallbackSystem.HasWrite) - { - CoreComm.MemoryCallbackSystem.TriggerWrite(addr); - } + CoreComm.MemoryCallbackSystem.CallWrite(addr); } public void WriteHardware(ushort addr, byte value) diff --git a/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs b/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs index b1c0c50960..b1673262dc 100644 --- a/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs +++ b/BizHawk.Emulation/Consoles/Intellivision/MemoryMap.cs @@ -164,10 +164,7 @@ } } - if (CoreComm.MemoryCallbackSystem.HasRead) - { - CoreComm.MemoryCallbackSystem.TriggerRead(addr); - } + CoreComm.MemoryCallbackSystem.CallRead(addr); if (cart != null) { @@ -359,10 +356,7 @@ } } - if (CoreComm.MemoryCallbackSystem.HasWrite) - { - CoreComm.MemoryCallbackSystem.TriggerWrite(addr); - } + CoreComm.MemoryCallbackSystem.CallWrite(addr); return (cart || stic || psg); } diff --git a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs index c3c92a7d79..4038a9edec 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs @@ -477,12 +477,12 @@ namespace BizHawk.Emulation.Consoles.GB // we RefreshMemoryCallbacks() after the triggers in case the trigger turns itself off at that point - if (mcs.HasRead) - readcb = delegate(uint addr) { mcs.TriggerRead((int)addr); RefreshMemoryCallbacks(); }; + if (mcs.HasReads) + readcb = delegate(uint addr) { mcs.CallRead(addr); RefreshMemoryCallbacks(); }; else readcb = null; - if (mcs.HasWrite) - writecb = delegate(uint addr) { mcs.TriggerWrite((int)addr); RefreshMemoryCallbacks(); }; + if (mcs.HasWrites) + writecb = delegate(uint addr) { mcs.CallWrite(addr); RefreshMemoryCallbacks(); }; else writecb = null; diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs index 692b12b21f..c2e7590143 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Core.cs @@ -554,10 +554,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo ret = sysbus_watch[addr].ApplyGameGenie(ret); } - if (CoreComm.MemoryCallbackSystem.HasRead) - { - CoreComm.MemoryCallbackSystem.TriggerRead(addr); - } + CoreComm.MemoryCallbackSystem.CallRead(addr); DB = ret; @@ -611,10 +608,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo board.WritePRG(addr - 0x8000, value); } - if (CoreComm.MemoryCallbackSystem.HasWrite) - { - CoreComm.MemoryCallbackSystem.TriggerWrite(addr); - } + CoreComm.MemoryCallbackSystem.CallWrite(addr); } } diff --git a/BizHawk.Emulation/Consoles/PC Engine/MemoryMap.cs b/BizHawk.Emulation/Consoles/PC Engine/MemoryMap.cs index 3790a1af2c..9a123f908b 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/MemoryMap.cs +++ b/BizHawk.Emulation/Consoles/PC Engine/MemoryMap.cs @@ -35,10 +35,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx return 0xFF; } - if (CoreComm.MemoryCallbackSystem.HasRead) - { - CoreComm.MemoryCallbackSystem.TriggerRead(addr); - } + CoreComm.MemoryCallbackSystem.CallRead((uint)addr); Log.Error("MEM", "UNHANDLED READ: {0:X6}", addr); return 0xFF; @@ -76,10 +73,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx else Log.Error("MEM", "UNHANDLED WRITE: {0:X6}:{1:X2}", addr, value); - if (CoreComm.MemoryCallbackSystem.HasWrite) - { - CoreComm.MemoryCallbackSystem.TriggerWrite(addr); - } + CoreComm.MemoryCallbackSystem.CallWrite((uint)addr); } } } \ No newline at end of file diff --git a/BizHawk.Emulation/Consoles/Sega/SMS/MemoryMap.Sega.cs b/BizHawk.Emulation/Consoles/Sega/SMS/MemoryMap.Sega.cs index 83addfe8df..5250bfc53c 100644 --- a/BizHawk.Emulation/Consoles/Sega/SMS/MemoryMap.Sega.cs +++ b/BizHawk.Emulation/Consoles/Sega/SMS/MemoryMap.Sega.cs @@ -43,10 +43,7 @@ ret = SystemRam[address & RamSizeMask]; } - if (CoreComm.MemoryCallbackSystem.HasRead) - { - CoreComm.MemoryCallbackSystem.TriggerRead(address); - } + CoreComm.MemoryCallbackSystem.CallRead(address); return ret; } @@ -81,10 +78,7 @@ return; } - if (CoreComm.MemoryCallbackSystem.HasWrite) - { - CoreComm.MemoryCallbackSystem.TriggerWrite(address); - } + CoreComm.MemoryCallbackSystem.CallWrite((uint)address); } void InitSegaMapper()