diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs
index 580af5ea11..19ea90d2ee 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs
@@ -147,6 +147,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
if (CD != null)
CoreComm.UsesDriveLed = true;
+
+ InitMemCallbacks();
+ KillMemCallbacks();
}
catch
{
@@ -366,6 +369,9 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
IsLagFrame = true;
Frame++;
drivelight = false;
+
+ RefreshMemCallbacks();
+
LibGPGX.gpgx_advance();
update_video();
update_audio();
@@ -598,6 +604,30 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
LibGPGX.gpgx_get_vdp_view(view);
}
+ LibGPGX.mem_cb ExecCallback;
+ LibGPGX.mem_cb ReadCallback;
+ LibGPGX.mem_cb WriteCallback;
+
+ void InitMemCallbacks()
+ {
+ ExecCallback = new LibGPGX.mem_cb(a => CoreComm.MemoryCallbackSystem.CallExecute(a));
+ ReadCallback = new LibGPGX.mem_cb(a => CoreComm.MemoryCallbackSystem.CallRead(a));
+ WriteCallback = new LibGPGX.mem_cb(a => CoreComm.MemoryCallbackSystem.CallWrite(a));
+ }
+
+ void RefreshMemCallbacks()
+ {
+ LibGPGX.gpgx_set_mem_callback(
+ CoreComm.MemoryCallbackSystem.HasReads ? ReadCallback : null,
+ CoreComm.MemoryCallbackSystem.HasWrites ? WriteCallback : null,
+ CoreComm.MemoryCallbackSystem.HasExecutes ? ExecCallback : null);
+ }
+
+ void KillMemCallbacks()
+ {
+ LibGPGX.gpgx_set_mem_callback(null, null, null);
+ }
+
#endregion
public void Dispose()
@@ -608,6 +638,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
throw new Exception();
if (SaveRamModified)
DisposedSaveRam = ReadSaveRam();
+ KillMemCallbacks();
AttachedCore = null;
disposed = true;
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs
index 3e846c94b9..de77cf4b8d 100644
--- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/LibGPGX.cs
@@ -115,6 +115,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_set_input_callback(input_cb cb);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void mem_cb(uint addr);
+
+ [DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void gpgx_set_mem_callback(mem_cb read, mem_cb write, mem_cb exec);
+
///
/// not every flag is valid for every device!
///
diff --git a/genplus-gx/cinterface/callbacks.h b/genplus-gx/cinterface/callbacks.h
new file mode 100644
index 0000000000..c5df5a5c08
--- /dev/null
+++ b/genplus-gx/cinterface/callbacks.h
@@ -0,0 +1,8 @@
+#ifndef CALLBACKS_H
+#define CALLBACKS_H
+
+extern void (*biz_execcb)(unsigned addr);
+extern void (*biz_readcb)(unsigned addr);
+extern void (*biz_writecb)(unsigned addr);
+
+#endif
diff --git a/genplus-gx/cinterface/cinterface.c b/genplus-gx/cinterface/cinterface.c
index dce3f4386c..4d33c08a57 100644
--- a/genplus-gx/cinterface/cinterface.c
+++ b/genplus-gx/cinterface/cinterface.c
@@ -1,6 +1,7 @@
#include
#include
#include
+#include "callbacks.h"
#ifdef _MSC_VER
#define snprintf _snprintf
@@ -48,6 +49,10 @@ static uint8_t brm_format[0x40] =
extern void zap(void);
+void (*biz_execcb)(unsigned addr) = NULL;
+void (*biz_readcb)(unsigned addr) = NULL;
+void (*biz_writecb)(unsigned addr) = NULL;
+
static void update_viewport(void)
{
vwidth = bitmap.viewport.w + (bitmap.viewport.x * 2);
@@ -519,6 +524,13 @@ GPGX_EX void gpgx_reset(int hard)
gen_reset(0);
}
+GPGX_EX void gpgx_set_mem_callback(void (*read)(unsigned), void (*write)(unsigned), void (*exec)(unsigned))
+{
+ biz_readcb = read;
+ biz_writecb = write;
+ biz_execcb = exec;
+}
+
typedef struct
{
unsigned int value;
diff --git a/genplus-gx/core/m68k/m68kcpu.c b/genplus-gx/core/m68k/m68kcpu.c
index 1b67409feb..e783102122 100644
--- a/genplus-gx/core/m68k/m68kcpu.c
+++ b/genplus-gx/core/m68k/m68kcpu.c
@@ -1,3 +1,5 @@
+#include "../cinterface/callbacks.h"
+
/* ======================================================================== */
/* MAIN 68K CORE */
/* ======================================================================== */
@@ -289,6 +291,9 @@ void m68k_run(unsigned int cycles)
/* Set the address space for reads */
m68ki_use_data_space() /* auto-disable (see m68kcpu.h) */
+ if (biz_execcb)
+ biz_execcb(REG_PC);
+
/* Decode next instruction */
REG_IR = m68ki_read_imm_16();
diff --git a/genplus-gx/core/m68k/m68kcpu.h b/genplus-gx/core/m68k/m68kcpu.h
index 317f2cdd12..efd465c8bb 100644
--- a/genplus-gx/core/m68k/m68kcpu.h
+++ b/genplus-gx/core/m68k/m68kcpu.h
@@ -14,6 +14,7 @@
#endif /* M68K_EMULATE_ADDRESS_ERROR */
#include "m68k.h"
+#include "../cinterface/callbacks.h"
/* ======================================================================== */
@@ -867,6 +868,8 @@ INLINE uint m68ki_read_imm_32(void)
INLINE uint m68ki_read_8_fc(uint address, uint fc)
{
cpu_memory_map *temp = &m68ki_cpu.memory_map[((address)>>16)&0xff];;
+ if (biz_readcb)
+ biz_readcb(address);
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
@@ -877,6 +880,8 @@ INLINE uint m68ki_read_8_fc(uint address, uint fc)
INLINE uint m68ki_read_16_fc(uint address, uint fc)
{
cpu_memory_map *temp;
+ if (biz_readcb)
+ biz_readcb(address);
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */
@@ -889,6 +894,8 @@ INLINE uint m68ki_read_16_fc(uint address, uint fc)
INLINE uint m68ki_read_32_fc(uint address, uint fc)
{
cpu_memory_map *temp;
+ if (biz_readcb)
+ biz_readcb(address);
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */
@@ -901,6 +908,8 @@ INLINE uint m68ki_read_32_fc(uint address, uint fc)
INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)
{
cpu_memory_map *temp;
+ if (biz_writecb)
+ biz_writecb(address);
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
@@ -912,6 +921,8 @@ INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)
INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
{
cpu_memory_map *temp;
+ if (biz_writecb)
+ biz_writecb(address);
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
@@ -924,6 +935,8 @@ INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
{
cpu_memory_map *temp;
+ if (biz_writecb)
+ biz_writecb(address);
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
m68ki_check_address_error(address, MODE_WRITE, fc) /* auto-disable (see m68kcpu.h) */
diff --git a/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj b/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj
index 8a1c256c38..f50da1adc5 100644
--- a/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj
+++ b/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj
@@ -63,6 +63,7 @@
+
diff --git a/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters b/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters
index 2544ead68a..676eb6025d 100644
--- a/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters
+++ b/genplus-gx/libretro/msvc/msvc-2010/msvc-2010.vcxproj.filters
@@ -392,5 +392,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/output/dll/libgenplusgx.dll b/output/dll/libgenplusgx.dll
index 56c51d8975..88e894e823 100644
Binary files a/output/dll/libgenplusgx.dll and b/output/dll/libgenplusgx.dll differ