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);