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