diff --git a/BizHawk.Emulation.Common/Interfaces/CoreComms.cs b/BizHawk.Emulation.Common/Interfaces/CoreComms.cs index cb70c04d80..131bce5d83 100644 --- a/BizHawk.Emulation.Common/Interfaces/CoreComms.cs +++ b/BizHawk.Emulation.Common/Interfaces/CoreComms.cs @@ -150,6 +150,9 @@ namespace BizHawk.Emulation.Common { _list.Clear(); } + + // why was this missing? + public bool Has { get { return _list.Any(); } } } public class MemoryCallbackSystem diff --git a/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs b/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs index 609d41ee10..b56528c4b7 100644 --- a/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs +++ b/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs @@ -127,6 +127,18 @@ namespace BizHawk.Emulation.Cores.WonderSwan [DllImport(dd, CallingConvention = cc)] public static extern void bizswan_txtstateload(IntPtr core, [In]ref TextStateFPtrs ff); + [DllImport(dd, CallingConvention = cc)] + public static extern void bizswan_setmemorycallbacks(IntPtr core, MemoryCallback rcb, MemoryCallback ecb, MemoryCallback wcb); + + [DllImport(dd, CallingConvention = cc)] + public static extern void bizswan_setbuttoncallback(IntPtr core, ButtonCallback bcb); + + [UnmanagedFunctionPointer(cc)] + public delegate void MemoryCallback(uint addr); + + [UnmanagedFunctionPointer(cc)] + public delegate void ButtonCallback(); + /// /// return a CPU register /// diff --git a/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs b/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs index b533e3fcd4..eb7fb2751c 100644 --- a/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs +++ b/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs @@ -120,6 +120,8 @@ namespace BizHawk.Emulation.Cores.WonderSwan savebuff = new byte[BizSwan.bizswan_binstatesize(Core)]; savebuff2 = new byte[savebuff.Length + 13]; + + InitDebugCallbacks(); } catch { @@ -142,6 +144,8 @@ namespace BizHawk.Emulation.Cores.WonderSwan Frame++; IsLagFrame = true; + SetDebugCallbacks(); + if (Controller["Power"]) BizSwan.bizswan_reset(Core); @@ -352,6 +356,46 @@ namespace BizHawk.Emulation.Cores.WonderSwan throw new NotImplementedException(); } + BizSwan.MemoryCallback ReadCallbackD; + BizSwan.MemoryCallback WriteCallbackD; + BizSwan.MemoryCallback ExecCallbackD; + BizSwan.ButtonCallback ButtonCallbackD; + + void ReadCallback(uint addr) + { + CoreComm.MemoryCallbackSystem.CallRead(addr); + } + void WriteCallback(uint addr) + { + CoreComm.MemoryCallbackSystem.CallWrite(addr); + } + void ExecCallback(uint addr) + { + CoreComm.MemoryCallbackSystem.CallExecute(addr); + } + void ButtonCallback() + { + CoreComm.InputCallback.Call(); + } + + void InitDebugCallbacks() + { + ReadCallbackD = new BizSwan.MemoryCallback(ReadCallback); + WriteCallbackD = new BizSwan.MemoryCallback(WriteCallback); + ExecCallbackD = new BizSwan.MemoryCallback(ExecCallback); + ButtonCallbackD = new BizSwan.ButtonCallback(ButtonCallback); + } + + void SetDebugCallbacks() + { + BizSwan.bizswan_setmemorycallbacks(Core, + CoreComm.MemoryCallbackSystem.HasReads ? ReadCallbackD : null, + CoreComm.MemoryCallbackSystem.HasWrites ? WriteCallbackD : null, + CoreComm.MemoryCallbackSystem.HasExecutes ? ExecCallbackD : null); + BizSwan.bizswan_setbuttoncallback(Core, + CoreComm.InputCallback.Has ? ButtonCallbackD : null); + } + #endregion #region Settings diff --git a/output/dll/bizswan.dll b/output/dll/bizswan.dll index baf1af5707..68a35c4844 100644 Binary files a/output/dll/bizswan.dll and b/output/dll/bizswan.dll differ diff --git a/wonderswan/memory.cpp b/wonderswan/memory.cpp index 133792891c..9d4a6e9f91 100644 --- a/wonderswan/memory.cpp +++ b/wonderswan/memory.cpp @@ -183,6 +183,9 @@ namespace MDFN_IEN_WSWAN } case 0xb5: { + Lagged = false; + if (ButtonHook) + ButtonHook(); uint8 ret = (ButtonWhich << 4) | ButtonReadLatch; return(ret); } @@ -252,7 +255,7 @@ namespace MDFN_IEN_WSWAN case 0xB3: CommControl = V & 0xF0; break; case 0xb5: ButtonWhich = V >> 4; - Lagged = false; + // Lagged = false; // why was this being set here? ButtonReadLatch = 0; if(ButtonWhich & 0x4) /*buttons*/ diff --git a/wonderswan/memory.h b/wonderswan/memory.h index 3ccfcd5c2a..3140d8a718 100644 --- a/wonderswan/memory.h +++ b/wonderswan/memory.h @@ -51,6 +51,9 @@ private: bool language; +public: + void (*ButtonHook)(); + public: System *sys; templatevoid SyncState(NewState *ns); diff --git a/wonderswan/system.cpp b/wonderswan/system.cpp index 18af564154..01ad02322c 100644 --- a/wonderswan/system.cpp +++ b/wonderswan/system.cpp @@ -203,6 +203,8 @@ namespace MDFN_IEN_WSWAN return true; } + // this is more than just being defensive; these classes do + // in some cases rely on zero filled constuct state void *System::operator new(std::size_t size) { void *p = ::operator new(size); @@ -404,4 +406,16 @@ namespace MDFN_IEN_WSWAN { s->SaveRamClearHacky(*settings); } + + EXPORT void bizswan_setmemorycallbacks(System *s, void (*rcb)(uint32), void (*ecb)(uint32), void (*wcb)(uint32)) + { + s->cpu.ReadHook = rcb; + s->cpu.WriteHook = wcb; + s->cpu.ExecHook = ecb; + } + + EXPORT void bizswan_setbuttoncallback(System *s, void (*bcb)()) + { + s->memory.ButtonHook = bcb; + } } diff --git a/wonderswan/v30mz-private.h b/wonderswan/v30mz-private.h index 261b7b0c98..ca123ef107 100644 --- a/wonderswan/v30mz-private.h +++ b/wonderswan/v30mz-private.h @@ -1,9 +1,9 @@ -#define cpu_readop sys->memory.Read20 +//#define cpu_readop sys->memory.Read20 //cpu_readmem20 -#define cpu_readop_arg sys->memory.Read20 +//#define cpu_readop_arg sys->memory.Read20 //cpu_readmem20 -#define cpu_readmem20 sys->memory.Read20 -#define cpu_writemem20 sys->memory.Write20 +//#define cpu_readmem20 sys->memory.Read20 +//#define cpu_writemem20 sys->memory.Write20 #define cpu_readport sys->memory.readport #define cpu_writeport sys->memory.writeport diff --git a/wonderswan/v30mz.cpp b/wonderswan/v30mz.cpp index 18e6f16398..76cfe7601a 100644 --- a/wonderswan/v30mz.cpp +++ b/wonderswan/v30mz.cpp @@ -1027,6 +1027,33 @@ namespace MDFN_IEN_WSWAN } + uint8 V30MZ::cpu_readop(uint32 addr) + { + if (ExecHook) + ExecHook(addr); + return sys->memory.Read20(addr); + } + uint8 V30MZ::cpu_readop_arg(uint32 addr) + { + // only forward the first opcode byte to callback + return sys->memory.Read20(addr); + } + uint8 V30MZ::cpu_readmem20(uint32 addr) + { + if (ReadHook) + ReadHook(addr); + return sys->memory.Read20(addr); + } + void V30MZ::cpu_writemem20(uint32 addr, uint8 val) + { + sys->memory.Write20(addr, val); + if (WriteHook) + WriteHook(addr); + } + + + + SYNCFUNC(V30MZ) { NSS(old_CS); diff --git a/wonderswan/v30mz.h b/wonderswan/v30mz.h index 7ef1a5dbbc..1d5bd897f7 100644 --- a/wonderswan/v30mz.h +++ b/wonderswan/v30mz.h @@ -80,8 +80,6 @@ private: } RM; } Mod_RM; -private: - private: void nec_interrupt(unsigned int_num); bool CheckInHLT(); @@ -139,6 +137,18 @@ private: typedef unsigned(V30MZ::*EAFPtr)(); EAFPtr GetEA[192]; + // memory callback system plumbing +public: + void (*ReadHook)(uint32 addr); + void (*WriteHook)(uint32 addr); + void (*ExecHook)(uint32 addr); +private: + uint8 cpu_readop(uint32 addr); + uint8 cpu_readop_arg(uint32 addr); + uint8 cpu_readmem20(uint32 addr); + void cpu_writemem20(uint32 addr, uint8 val); + + public: System *sys; templatevoid SyncState(NewState *ns);