diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs
index 0e6fa29464..13d2fab0b0 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs
@@ -86,6 +86,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
}
public void FrameAdvance(bool render, bool rendersound)
{
+ RefreshMemoryCallbacks();
+
if (Controller["Reset"])
{
api.soft_reset();
@@ -262,6 +264,32 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
public bool BinarySaveStatesPreferred { get { return true; } }
+ #region memorycallback
+
+ mupen64plusApi.MemoryCallback readcb;
+ mupen64plusApi.MemoryCallback writecb;
+
+ void RefreshMemoryCallbacks()
+ {
+ var mcs = CoreComm.MemoryCallbackSystem;
+
+ // we RefreshMemoryCallbacks() after the triggers in case the trigger turns itself off at that point
+
+ if (mcs.HasReads)
+ readcb = delegate(uint addr) { mcs.CallRead(addr); RefreshMemoryCallbacks(); };
+ else
+ readcb = null;
+ if (mcs.HasWrites)
+ writecb = delegate(uint addr) { mcs.CallWrite(addr); RefreshMemoryCallbacks(); };
+ else
+ writecb = null;
+
+ api.setReadCallback(readcb);
+ api.setWriteCallback(writecb);
+ }
+
+ #endregion
+
#region memorydomains
private MemoryDomain MakeMemoryDomain(string name, mupen64plusApi.N64_MEMORY id, MemoryDomain.Endian endian)
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/mupen64plusApi.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/mupen64plusApi.cs
index 450cff1205..9bb66014af 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/mupen64plusApi.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/mupen64plusApi.cs
@@ -401,6 +401,27 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void StartupCallback();
+ ///
+ /// Type of the read/write memory callbacks
+ ///
+ /// The address which the cpu is read/writing
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void MemoryCallback(uint address);
+
+ ///
+ /// Sets the memory read callback
+ ///
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void SetReadCallback(MemoryCallback callback);
+ SetReadCallback m64pSetReadCallback;
+
+ ///
+ /// Sets the memory write callback
+ ///
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void SetWriteCallback(MemoryCallback callback);
+ SetWriteCallback m64pSetWriteCallback;
+
// DLL handles
IntPtr CoreDll;
IntPtr GfxDll;
@@ -557,6 +578,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
m64psave_saveram = (save_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "save_saveram"), typeof(save_saveram));
m64pload_saveram = (load_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "load_saveram"), typeof(load_saveram));
+ m64pSetReadCallback = (SetReadCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "SetReadCallback"), typeof(SetReadCallback));
+ m64pSetWriteCallback = (SetWriteCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "SetWriteCallback"), typeof(SetWriteCallback));
+
GfxPluginStartup = (PluginStartup)Marshal.GetDelegateForFunctionPointer(GetProcAddress(GfxDll, "PluginStartup"), typeof(PluginStartup));
GfxPluginShutdown = (PluginShutdown)Marshal.GetDelegateForFunctionPointer(GetProcAddress(GfxDll, "PluginShutdown"), typeof(PluginShutdown));
GFXReadScreen2 = (ReadScreen2)Marshal.GetDelegateForFunctionPointer(GetProcAddress(GfxDll, "ReadScreen2"), typeof(ReadScreen2));
@@ -786,6 +810,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
m64pload_saveram(src);
}
+ public void setReadCallback(MemoryCallback callback)
+ {
+ m64pSetReadCallback(callback);
+ }
+
+ public void setWriteCallback(MemoryCallback callback)
+ {
+ m64pSetWriteCallback(callback);
+ }
+
public void Dispose()
{
if (!disposed)
diff --git a/libmupen64plus/mupen64plus-core/src/memory/dma.c b/libmupen64plus/mupen64plus-core/src/memory/dma.c
index f98e7fe436..481892664d 100644
--- a/libmupen64plus/mupen64plus-core/src/memory/dma.c
+++ b/libmupen64plus/mupen64plus-core/src/memory/dma.c
@@ -106,6 +106,8 @@ void dma_pi_read(void)
{
for (i=0; i < (pi_register.pi_rd_len_reg & 0xFFFFFF)+1; i++)
{
+ READCBADDR(0x80000000 | ((pi_register.pi_dram_addr_reg+i)^S8));
+
sram[((pi_register.pi_cart_addr_reg-0x08000000)+i)^S8] =
((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8];
}
@@ -145,6 +147,8 @@ void dma_pi_write(void)
for (i=0; i<(int)(pi_register.pi_wr_len_reg & 0xFFFFFF)+1; i++)
{
+ WRITECBADDR(0x80000000 | ((pi_register.pi_dram_addr_reg+i)^S8));
+
((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]=
sram[(((pi_register.pi_cart_addr_reg-0x08000000)&0xFFFF)+i)^S8];
}
@@ -203,6 +207,9 @@ void dma_pi_write(void)
{
unsigned long rdram_address1 = pi_register.pi_dram_addr_reg+i+0x80000000;
unsigned long rdram_address2 = pi_register.pi_dram_addr_reg+i+0xa0000000;
+
+ WRITECBADDR(0x80000000 | ((pi_register.pi_dram_addr_reg+i)^S8));
+
((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]=
rom[(((pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF)+i)^S8];
@@ -233,6 +240,8 @@ void dma_pi_write(void)
{
for (i=0; i<(int)longueur; i++)
{
+ WRITECBADDR(0x80000000 | ((pi_register.pi_dram_addr_reg+i)^S8));
+
((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]=
rom[(((pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF)+i)^S8];
}
@@ -249,6 +258,8 @@ void dma_pi_write(void)
case 3:
case 6:
{
+ WRITECBADDR(0x80000000 | (0x318/4));
+
if (ConfigGetParamInt(g_CoreConfig, "DisableExtraMem"))
{
rdram[0x318/4] = 0x400000;
@@ -261,6 +272,8 @@ void dma_pi_write(void)
}
case 5:
{
+ WRITECBADDR(0x80000000 | (0x3F0/4));
+
if (ConfigGetParamInt(g_CoreConfig, "DisableExtraMem"))
{
rdram[0x3F0/4] = 0x400000;
@@ -299,6 +312,8 @@ void dma_sp_write(void)
for(j=0; j> 32);
rdram[pi_register.pi_dram_addr_reg/4+1] = (unsigned int)(flashram_info.status);
break;
case READ_MODE:
for (i=0; i<(pi_register.pi_wr_len_reg & 0x0FFFFFF)+1; i++)
{
+ READCBADDR(0x80000000 | ((pi_register.pi_dram_addr_reg+i)^S8));
+
((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]=
flashram[(((pi_register.pi_cart_addr_reg-0x08000000)&0xFFFF)*2+i)^S8];
}
diff --git a/libmupen64plus/mupen64plus-core/src/memory/flashram.h b/libmupen64plus/mupen64plus-core/src/memory/flashram.h
index e07e9d4d2a..20f3deab82 100644
--- a/libmupen64plus/mupen64plus-core/src/memory/flashram.h
+++ b/libmupen64plus/mupen64plus-core/src/memory/flashram.h
@@ -34,4 +34,7 @@ void flashram_command(unsigned int command);
unsigned int flashram_status(void);
void dma_read_flashram(void);
void dma_write_flashram(void);
-void flashram_format(void);
\ No newline at end of file
+void flashram_format(void);
+
+extern void (*readCB)(unsigned int);
+extern void (*writeCB)(unsigned int);
\ No newline at end of file
diff --git a/libmupen64plus/mupen64plus-core/src/memory/memory.c b/libmupen64plus/mupen64plus-core/src/memory/memory.c
index caf65a0e9a..458d0fbf26 100644
--- a/libmupen64plus/mupen64plus-core/src/memory/memory.c
+++ b/libmupen64plus/mupen64plus-core/src/memory/memory.c
@@ -133,6 +133,9 @@ static FrameBufferInfo frameBufferInfos[6];
static char framebufferRead[0x800];
static int firstFrameBufferSetting;
+void (*readCB)(unsigned int) = NULL;
+void (*writeCB)(unsigned int) = NULL;
+
// uncomment to output count of calls to write_rdram():
//#define COUNT_WRITE_RDRAM_CALLS 1
@@ -1544,39 +1547,51 @@ static void update_DPC(void)
void read_nothing(void)
{
+ READCB();
+
if (address == 0xa5000508) *rdword = 0xFFFFFFFF;
else *rdword = 0;
}
void read_nothingb(void)
{
+ READCB();
+
*rdword = 0;
}
void read_nothingh(void)
{
+ READCB();
+
*rdword = 0;
}
void read_nothingd(void)
{
+ READCB();
+
*rdword = 0;
}
void write_nothing(void)
{
+ WRITECB();
}
void write_nothingb(void)
{
+ WRITECB();
}
void write_nothingh(void)
{
+ WRITECB();
}
void write_nothingd(void)
{
+ WRITECB();
}
void read_nomem(void)
@@ -1653,21 +1668,29 @@ void write_nomemd(void)
void read_rdram(void)
{
+ READCB();
+
*rdword = *((unsigned int *)(rdramb + (address & 0xFFFFFF)));
}
void read_rdramb(void)
{
+ READCB();
+
*rdword = *(rdramb + ((address & 0xFFFFFF)^S8));
}
void read_rdramh(void)
{
+ READCB();
+
*rdword = *((unsigned short *)(rdramb + ((address & 0xFFFFFF)^S16)));
}
void read_rdramd(void)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*(unsigned int *)(rdramb + (address & 0xFFFFFF))) << 32) |
((*(unsigned int *)(rdramb + (address & 0xFFFFFF) + 4)));
}
@@ -1762,6 +1785,8 @@ void read_rdramFBd(void)
void write_rdram(void)
{
+ WRITECB();
+
#if defined( COUNT_WRITE_RDRAM_CALLS )
printf( "write_rdram, word=%i, count: %i", word, writerdram_count );
writerdram_count++;
@@ -1771,16 +1796,22 @@ void write_rdram(void)
void write_rdramb(void)
{
+ WRITECB();
+
*((rdramb + ((address & 0xFFFFFF)^S8))) = cpu_byte;
}
void write_rdramh(void)
{
+ WRITECB();
+
*(unsigned short *)((rdramb + ((address & 0xFFFFFF)^S16))) = hword;
}
void write_rdramd(void)
{
+ WRITECB();
+
*((unsigned int *)(rdramb + (address & 0xFFFFFF))) = (unsigned int) (dword >> 32);
*((unsigned int *)(rdramb + (address & 0xFFFFFF) + 4 )) = (unsigned int) (dword & 0xFFFFFFFF);
}
@@ -1859,46 +1890,62 @@ void write_rdramFBd(void)
void read_rdramreg(void)
{
+ READCB();
+
*rdword = *(readrdramreg[*address_low]);
}
void read_rdramregb(void)
{
+ READCB();
+
*rdword = *((unsigned char*)readrdramreg[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_rdramregh(void)
{
+ READCB();
+
*rdword = *((unsigned short*)((unsigned char*)readrdramreg[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_rdramregd(void)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*readrdramreg[*address_low])<<32) |
*readrdramreg[*address_low+4];
}
void write_rdramreg(void)
{
+ WRITECB();
+
*readrdramreg[*address_low] = word;
}
void write_rdramregb(void)
{
+ WRITECB();
+
*((unsigned char*)readrdramreg[*address_low & 0xfffc]
+ ((*address_low&3)^S8) ) = cpu_byte;
}
void write_rdramregh(void)
{
+ WRITECB();
+
*((unsigned short*)((unsigned char*)readrdramreg[*address_low & 0xfffc]
+ ((*address_low&3)^S16) )) = hword;
}
void write_rdramregd(void)
{
+ WRITECB();
+
*readrdramreg[*address_low] = (unsigned int) (dword >> 32);
*readrdramreg[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
}
@@ -1906,9 +1953,17 @@ void write_rdramregd(void)
void read_rsp_mem(void)
{
if (*address_low < 0x1000)
+ {
+ READCB();
+
*rdword = *((unsigned int *)(SP_DMEMb + (*address_low)));
+ }
else if (*address_low < 0x2000)
+ {
+ READCB();
+
*rdword = *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF)));
+ }
else
read_nomem();
}
@@ -1916,9 +1971,17 @@ void read_rsp_mem(void)
void read_rsp_memb(void)
{
if (*address_low < 0x1000)
+ {
+ READCB();
+
*rdword = *(SP_DMEMb + (*address_low^S8));
+ }
else if (*address_low < 0x2000)
+ {
+ READCB();
+
*rdword = *(SP_IMEMb + ((*address_low&0xFFF)^S8));
+ }
else
read_nomemb();
}
@@ -1926,9 +1989,17 @@ void read_rsp_memb(void)
void read_rsp_memh(void)
{
if (*address_low < 0x1000)
+ {
+ READCB();
+
*rdword = *((unsigned short *)(SP_DMEMb + (*address_low^S16)));
+ }
else if (*address_low < 0x2000)
+ {
+ READCB();
+
*rdword = *((unsigned short *)(SP_IMEMb + ((*address_low&0xFFF)^S16)));
+ }
else
read_nomemh();
}
@@ -1937,11 +2008,15 @@ void read_rsp_memd(void)
{
if (*address_low < 0x1000)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*(unsigned int *)(SP_DMEMb + (*address_low))) << 32) |
((*(unsigned int *)(SP_DMEMb + (*address_low) + 4)));
}
else if (*address_low < 0x2000)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*(unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) << 32) |
((*(unsigned int *)(SP_IMEMb + (*address_low&0xFFF) + 4)));
}
@@ -1952,9 +2027,17 @@ void read_rsp_memd(void)
void write_rsp_mem(void)
{
if (*address_low < 0x1000)
+ {
+ WRITECB();
+
*((unsigned int *)(SP_DMEMb + (*address_low))) = word;
+ }
else if (*address_low < 0x2000)
+ {
+ WRITECB();
+
*((unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) = word;
+ }
else
write_nomem();
}
@@ -1962,9 +2045,17 @@ void write_rsp_mem(void)
void write_rsp_memb(void)
{
if (*address_low < 0x1000)
+ {
+ WRITECB();
+
*(SP_DMEMb + (*address_low^S8)) = cpu_byte;
+ }
else if (*address_low < 0x2000)
+ {
+ WRITECB();
+
*(SP_IMEMb + ((*address_low&0xFFF)^S8)) = cpu_byte;
+ }
else
write_nomemb();
}
@@ -1972,9 +2063,17 @@ void write_rsp_memb(void)
void write_rsp_memh(void)
{
if (*address_low < 0x1000)
+ {
+ WRITECB();
+
*((unsigned short *)(SP_DMEMb + (*address_low^S16))) = hword;
+ }
else if (*address_low < 0x2000)
+ {
+ WRITECB();
+
*((unsigned short *)(SP_IMEMb + ((*address_low&0xFFF)^S16))) = hword;
+ }
else
write_nomemh();
}
@@ -1983,11 +2082,15 @@ void write_rsp_memd(void)
{
if (*address_low < 0x1000)
{
+ WRITECB();
+
*((unsigned int *)(SP_DMEMb + *address_low)) = (unsigned int) (dword >> 32);
*((unsigned int *)(SP_DMEMb + *address_low + 4 )) = (unsigned int) (dword & 0xFFFFFFFF);
}
else if (*address_low < 0x2000)
{
+ WRITECB();
+
*((unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) = (unsigned int) (dword >> 32);
*((unsigned int *)(SP_IMEMb + (*address_low&0xFFF) + 4 )) = (unsigned int) (dword & 0xFFFFFFFF);
}
@@ -1997,6 +2100,8 @@ void write_rsp_memd(void)
void read_rsp_reg(void)
{
+ READCB();
+
*rdword = *(readrspreg[*address_low]);
switch (*address_low)
{
@@ -2008,6 +2113,8 @@ void read_rsp_reg(void)
void read_rsp_regb(void)
{
+ READCB();
+
*rdword = *((unsigned char*)readrspreg[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
switch (*address_low)
@@ -2023,6 +2130,8 @@ void read_rsp_regb(void)
void read_rsp_regh(void)
{
+ READCB();
+
*rdword = *((unsigned short*)((unsigned char*)readrspreg[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
switch (*address_low)
@@ -2036,6 +2145,8 @@ void read_rsp_regh(void)
void read_rsp_regd(void)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*readrspreg[*address_low])<<32) |
*readrspreg[*address_low+4];
switch (*address_low)
@@ -2048,6 +2159,8 @@ void read_rsp_regd(void)
void write_rsp_reg(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x10:
@@ -2075,6 +2188,8 @@ void write_rsp_reg(void)
void write_rsp_regb(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x10:
@@ -2121,6 +2236,8 @@ void write_rsp_regb(void)
void write_rsp_regh(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x10:
@@ -2155,6 +2272,8 @@ void write_rsp_regh(void)
void write_rsp_regd(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x10:
@@ -2180,75 +2299,101 @@ void write_rsp_regd(void)
void read_rsp(void)
{
+ READCB();
+
*rdword = *(readrsp[*address_low]);
}
void read_rspb(void)
{
+ READCB();
+
*rdword = *((unsigned char*)readrsp[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_rsph(void)
{
+ READCB();
+
*rdword = *((unsigned short*)((unsigned char*)readrsp[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_rspd(void)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*readrsp[*address_low])<<32) |
*readrsp[*address_low+4];
}
void write_rsp(void)
{
+ WRITECB();
+
*readrsp[*address_low] = word;
}
void write_rspb(void)
{
+ WRITECB();
+
*((unsigned char*)readrsp[*address_low & 0xfffc]
+ ((*address_low&3)^S8) ) = cpu_byte;
}
void write_rsph(void)
{
+ WRITECB();
+
*((unsigned short*)((unsigned char*)readrsp[*address_low & 0xfffc]
+ ((*address_low&3)^S16) )) = hword;
}
void write_rspd(void)
{
+ WRITECB();
+
*readrsp[*address_low] = (unsigned int) (dword >> 32);
*readrsp[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
}
void read_dp(void)
{
+ READCB();
+
*rdword = *(readdp[*address_low]);
}
void read_dpb(void)
{
+ READCB();
+
*rdword = *((unsigned char*)readdp[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_dph(void)
{
+ READCB();
+
*rdword = *((unsigned short*)((unsigned char*)readdp[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_dpd(void)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*readdp[*address_low])<<32) |
*readdp[*address_low+4];
}
void write_dp(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0xc:
@@ -2278,6 +2423,8 @@ void write_dp(void)
void write_dpb(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0xc:
@@ -2333,6 +2480,8 @@ void write_dpb(void)
void write_dph(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0xc:
@@ -2372,6 +2521,8 @@ void write_dph(void)
void write_dpd(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x8:
@@ -2399,75 +2550,101 @@ void write_dpd(void)
void read_dps(void)
{
+ READCB();
+
*rdword = *(readdps[*address_low]);
}
void read_dpsb(void)
{
+ READCB();
+
*rdword = *((unsigned char*)readdps[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_dpsh(void)
{
+ READCB();
+
*rdword = *((unsigned short*)((unsigned char*)readdps[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_dpsd(void)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*readdps[*address_low])<<32) |
*readdps[*address_low+4];
}
void write_dps(void)
{
+ WRITECB();
+
*readdps[*address_low] = word;
}
void write_dpsb(void)
{
+ WRITECB();
+
*((unsigned char*)readdps[*address_low & 0xfffc]
+ ((*address_low&3)^S8) ) = cpu_byte;
}
void write_dpsh(void)
{
+ WRITECB();
+
*((unsigned short*)((unsigned char*)readdps[*address_low & 0xfffc]
+ ((*address_low&3)^S16) )) = hword;
}
void write_dpsd(void)
{
+ WRITECB();
+
*readdps[*address_low] = (unsigned int) (dword >> 32);
*readdps[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
}
void read_mi(void)
{
+ READCB();
+
*rdword = *(readmi[*address_low]);
}
void read_mib(void)
{
+ READCB();
+
*rdword = *((unsigned char*)readmi[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_mih(void)
{
+ READCB();
+
*rdword = *((unsigned short*)((unsigned char*)readmi[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_mid(void)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*readmi[*address_low])<<32) |
*readmi[*address_low+4];
}
void write_mi(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -2487,6 +2664,8 @@ void write_mi(void)
void write_mib(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -2514,6 +2693,8 @@ void write_mib(void)
void write_mih(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -2537,6 +2718,8 @@ void write_mih(void)
void write_mid(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -2556,6 +2739,8 @@ void write_mid(void)
void read_vi(void)
{
+ READCB();
+
switch (*address_low)
{
case 0x10:
@@ -2569,6 +2754,8 @@ void read_vi(void)
void read_vib(void)
{
+ READCB();
+
switch (*address_low)
{
case 0x10:
@@ -2586,6 +2773,8 @@ void read_vib(void)
void read_vih(void)
{
+ READCB();
+
switch (*address_low)
{
case 0x10:
@@ -2601,6 +2790,8 @@ void read_vih(void)
void read_vid(void)
{
+ READCB();
+
switch (*address_low)
{
case 0x10:
@@ -2615,6 +2806,8 @@ void read_vid(void)
void write_vi(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -2655,6 +2848,9 @@ void update_vi_width(unsigned int word)
void write_vib(void)
{
int temp;
+
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -2699,6 +2895,9 @@ void write_vib(void)
void write_vih(void)
{
int temp;
+
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -2736,6 +2935,8 @@ void write_vih(void)
void write_vid(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -2767,6 +2968,8 @@ void write_vid(void)
void read_ai(void)
{
+ READCB();
+
switch (*address_low)
{
case 0x4:
@@ -2785,6 +2988,9 @@ void read_ai(void)
void read_aib(void)
{
unsigned int len;
+
+ READCB();
+
switch (*address_low)
{
case 0x4:
@@ -2807,6 +3013,9 @@ void read_aib(void)
void read_aih(void)
{
unsigned int len;
+
+ READCB();
+
switch (*address_low)
{
case 0x4:
@@ -2827,6 +3036,8 @@ void read_aih(void)
void read_aid(void)
{
+ READCB();
+
switch (*address_low)
{
case 0x0:
@@ -2847,6 +3058,9 @@ void read_aid(void)
void write_ai(void)
{
unsigned int freq,delay=0;
+
+ WRITECB();
+
switch (*address_low)
{
case 0x4:
@@ -2899,6 +3113,9 @@ void write_aib(void)
{
int temp;
unsigned int delay=0;
+
+ WRITECB();
+
switch (*address_low)
{
case 0x4:
@@ -2961,6 +3178,9 @@ void write_aih(void)
{
int temp;
unsigned int delay=0;
+
+ WRITECB();
+
switch (*address_low)
{
case 0x4:
@@ -3015,6 +3235,9 @@ void write_aih(void)
void write_aid(void)
{
unsigned int delay=0;
+
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -3062,29 +3285,39 @@ void write_aid(void)
void read_pi(void)
{
+ READCB();
+
*rdword = *(readpi[*address_low]);
}
void read_pib(void)
{
+ READCB();
+
*rdword = *((unsigned char*)readpi[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_pih(void)
{
+ READCB();
+
*rdword = *((unsigned short*)((unsigned char*)readpi[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_pid(void)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*readpi[*address_low])<<32) |
*readpi[*address_low+4];
}
void write_pi(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x8:
@@ -3119,6 +3352,8 @@ void write_pi(void)
void write_pib(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x8:
@@ -3180,6 +3415,8 @@ void write_pib(void)
void write_pih(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x8:
@@ -3231,6 +3468,8 @@ void write_pih(void)
void write_pid(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x8:
@@ -3261,75 +3500,101 @@ void write_pid(void)
void read_ri(void)
{
+ READCB();
+
*rdword = *(readri[*address_low]);
}
void read_rib(void)
{
+ READCB();
+
*rdword = *((unsigned char*)readri[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_rih(void)
{
+ READCB();
+
*rdword = *((unsigned short*)((unsigned char*)readri[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_rid(void)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*readri[*address_low])<<32) |
*readri[*address_low+4];
}
void write_ri(void)
{
+ WRITECB();
+
*readri[*address_low] = word;
}
void write_rib(void)
{
+ WRITECB();
+
*((unsigned char*)readri[*address_low & 0xfffc]
+ ((*address_low&3)^S8) ) = cpu_byte;
}
void write_rih(void)
{
+ WRITECB();
+
*((unsigned short*)((unsigned char*)readri[*address_low & 0xfffc]
+ ((*address_low&3)^S16) )) = hword;
}
void write_rid(void)
{
+ WRITECB();
+
*readri[*address_low] = (unsigned int) (dword >> 32);
*readri[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF);
}
void read_si(void)
{
+ READCB();
+
*rdword = *(readsi[*address_low]);
}
void read_sib(void)
{
+ READCB();
+
*rdword = *((unsigned char*)readsi[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_sih(void)
{
+ READCB();
+
*rdword = *((unsigned short*)((unsigned char*)readsi[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_sid(void)
{
+ READCB();
+
*rdword = ((unsigned long long int)(*readsi[*address_low])<<32) |
*readsi[*address_low+4];
}
void write_si(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -3357,6 +3622,8 @@ void write_si(void)
void write_sib(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -3399,6 +3666,8 @@ void write_sib(void)
void write_sih(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -3433,6 +3702,8 @@ void write_sih(void)
void write_sid(void)
{
+ WRITECB();
+
switch (*address_low)
{
case 0x0:
@@ -3457,6 +3728,8 @@ void write_sid(void)
void read_flashram_status(void)
{
+ READCB();
+
if (flashram_info.use_flashram != -1 && *address_low == 0)
{
*rdword = flashram_status();
@@ -3468,37 +3741,49 @@ void read_flashram_status(void)
void read_flashram_statusb(void)
{
+ READCB();
+
DebugMessage(M64MSG_ERROR, "read_flashram_statusb() not implemented");
}
void read_flashram_statush(void)
{
+ READCB();
+
DebugMessage(M64MSG_ERROR, "read_flashram_statush() not implemented");
}
void read_flashram_statusd(void)
{
+ READCB();
+
DebugMessage(M64MSG_ERROR, "read_flashram_statusd() not implemented");
}
void write_flashram_dummy(void)
{
+ WRITECB();
}
void write_flashram_dummyb(void)
{
+ WRITECB();
}
void write_flashram_dummyh(void)
{
+ WRITECB();
}
void write_flashram_dummyd(void)
{
+ WRITECB();
}
void write_flashram_command(void)
{
+ WRITECB();
+
if (flashram_info.use_flashram != -1 && *address_low == 0)
{
flashram_command(word);
@@ -3510,16 +3795,22 @@ void write_flashram_command(void)
void write_flashram_commandb(void)
{
+ WRITECB();
+
DebugMessage(M64MSG_ERROR, "write_flashram_commandb() not implemented");
}
void write_flashram_commandh(void)
{
+ WRITECB();
+
DebugMessage(M64MSG_ERROR, "write_flashram_commandh() not implemented");
}
void write_flashram_commandd(void)
{
+ WRITECB();
+
DebugMessage(M64MSG_ERROR, "write_flashram_commandd() not implemented");
}
@@ -3527,6 +3818,8 @@ static unsigned int lastwrite = 0;
void read_rom(void)
{
+ READCB();
+
if (lastwrite)
{
*rdword = lastwrite;
@@ -3538,27 +3831,37 @@ void read_rom(void)
void read_romb(void)
{
+ READCB();
+
*rdword = *(rom + ((address^S8) & 0x03FFFFFF));
}
void read_romh(void)
{
+ READCB();
+
*rdword = *((unsigned short *)(rom + ((address^S16) & 0x03FFFFFF)));
}
void read_romd(void)
{
+ READCB();
+
*rdword = ((unsigned long long)(*((unsigned int *)(rom+(address&0x03FFFFFF))))<<32)|
*((unsigned int *)(rom + ((address+4)&0x03FFFFFF)));
}
void write_rom(void)
{
+ WRITECB();
+
lastwrite = word;
}
void read_pif(void)
{
+ READCB();
+
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
DebugMessage(M64MSG_ERROR, "reading a word in PIF at invalid address 0x%x", address);
@@ -3571,6 +3874,8 @@ void read_pif(void)
void read_pifb(void)
{
+ READCB();
+
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
DebugMessage(M64MSG_ERROR, "reading a byte in PIF at invalid address 0x%x", address);
@@ -3583,6 +3888,8 @@ void read_pifb(void)
void read_pifh(void)
{
+ READCB();
+
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
DebugMessage(M64MSG_ERROR, "reading a hword in PIF at invalid address 0x%x", address);
@@ -3596,6 +3903,8 @@ void read_pifh(void)
void read_pifd(void)
{
+ READCB();
+
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
DebugMessage(M64MSG_ERROR, "reading a double word in PIF in invalid address 0x%x", address);
@@ -3609,6 +3918,8 @@ void read_pifd(void)
void write_pif(void)
{
+ WRITECB();
+
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
DebugMessage(M64MSG_ERROR, "writing a word in PIF at invalid address 0x%x", address);
@@ -3631,6 +3942,8 @@ void write_pif(void)
void write_pifb(void)
{
+ WRITECB();
+
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
DebugMessage(M64MSG_ERROR, "writing a byte in PIF at invalid address 0x%x", address);
@@ -3653,6 +3966,8 @@ void write_pifb(void)
void write_pifh(void)
{
+ WRITECB();
+
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
DebugMessage(M64MSG_ERROR, "writing a hword in PIF at invalid address 0x%x", address);
@@ -3676,6 +3991,8 @@ void write_pifh(void)
void write_pifd(void)
{
+ WRITECB();
+
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
DebugMessage(M64MSG_ERROR, "writing a double word in PIF at 0x%x", address);
@@ -3717,3 +4034,13 @@ unsigned int *fast_mem_access(unsigned int address)
else
return NULL;
}
+
+EXPORT void CALL SetReadCallback(void (*CB)(unsigned int))
+{
+ readCB = CB;
+}
+
+EXPORT void CALL SetWriteCallback(void (*CB)(unsigned int))
+{
+ writeCB = CB;
+}
\ No newline at end of file
diff --git a/libmupen64plus/mupen64plus-core/src/memory/memory.h b/libmupen64plus/mupen64plus-core/src/memory/memory.h
index a77094f6a2..e8827f3bb4 100644
--- a/libmupen64plus/mupen64plus-core/src/memory/memory.h
+++ b/libmupen64plus/mupen64plus-core/src/memory/memory.h
@@ -24,6 +24,12 @@
#include "osal/preproc.h"
+#define READCB() if (readCB) readCB(address)
+#define WRITECB() if (writeCB) writeCB(address)
+
+#define READCBADDR(addr) if (readCB) readCB(addr)
+#define WRITECBADDR(addr) if (writeCB) writeCB(addr)
+
int init_memory(int DoByteSwap);
void free_memory(void);
#define read_word_in_memory() readmem[address>>16]()
diff --git a/output/dll/mupen64plus.dll b/output/dll/mupen64plus.dll
index 737b953f60..ec968d66ad 100644
Binary files a/output/dll/mupen64plus.dll and b/output/dll/mupen64plus.dll differ