diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs
index 8423fd437b..f9d8d42534 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs
@@ -44,19 +44,35 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
throw new NotImplementedException();
}
- [FeatureNotImplemented]
public int TotalExecutedCycles
{
- get { throw new NotImplementedException(); }
+ get { return (int)Math.Max(_cycleCount, callbackCycleCount); }
}
+ private MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
public IMemoryCallbackSystem MemoryCallbacks => _memorycallbacks;
private LibGambatte.MemoryCallback _readcb;
private LibGambatte.MemoryCallback _writecb;
private LibGambatte.MemoryCallback _execcb;
- private MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
+ private void ReadCallback(uint address, ulong cycleOffset)
+ {
+ callbackCycleCount = _cycleCount + cycleOffset;
+ MemoryCallbacks.CallReads(address, "System Bus");
+ }
+
+ private void WriteCallback(uint address, ulong cycleOffset)
+ {
+ callbackCycleCount = _cycleCount + cycleOffset;
+ MemoryCallbacks.CallWrites(address, "System Bus");
+ }
+
+ private void ExecCallback(uint address, ulong cycleOffset)
+ {
+ callbackCycleCount = _cycleCount + cycleOffset;
+ MemoryCallbacks.CallExecutes(address, "System Bus");
+ }
///
/// for use in dual core
@@ -68,9 +84,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
private void InitMemoryCallbacks()
{
- _readcb = addr => MemoryCallbacks.CallReads(addr, "System Bus");
- _writecb = addr => MemoryCallbacks.CallWrites(addr, "System Bus");
- _execcb = addr => MemoryCallbacks.CallExecutes(addr, "System Bus");
+ _readcb = new LibGambatte.MemoryCallback(ReadCallback);
+ _writecb = new LibGambatte.MemoryCallback(WriteCallback);
+ _execcb = new LibGambatte.MemoryCallback(ExecCallback);
_memorycallbacks.ActiveChanged += RefreshMemoryCallbacks;
}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs
index 4fa2a67ec4..1f1891e1a5 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs
@@ -244,6 +244,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
/// total cycles actually executed
///
private ulong _cycleCount = 0;
+ private ulong callbackCycleCount = 0;
///
/// number of extra cycles we overran in the last frame
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
index ecb9b432ca..1a05daea20 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
@@ -190,7 +190,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
///
/// the address which the cpu is read\writing
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate void MemoryCallback(uint address);
+ public delegate void MemoryCallback(uint address, ulong cycleOffset);
///
/// type of the CDLogger callback
diff --git a/libgambatte/include/gambatte.h b/libgambatte/include/gambatte.h
index 2b953984a9..94bab7befb 100644
--- a/libgambatte/include/gambatte.h
+++ b/libgambatte/include/gambatte.h
@@ -28,6 +28,7 @@
namespace gambatte {
enum { BG_PALETTE = 0, SP1_PALETTE = 1, SP2_PALETTE = 2 };
+typedef void (*MemoryCallback)(int32_t address, int64_t cycleOffset);
typedef void (*CDCallback)(int32_t addr, int32_t addrtype, int32_t flags);
enum eCDLog_AddrType
@@ -105,9 +106,9 @@ public:
/** Sets the callback used for getting input state. */
void setInputGetter(unsigned (*getInput)());
- void setReadCallback(void (*callback)(unsigned));
- void setWriteCallback(void (*callback)(unsigned));
- void setExecCallback(void (*callback)(unsigned));
+ void setReadCallback(MemoryCallback);
+ void setWriteCallback(MemoryCallback);
+ void setExecCallback(MemoryCallback);
void setCDCallback(CDCallback);
void setTraceCallback(void (*callback)(void *));
void setScanlineCallback(void (*callback)(), int sl);
diff --git a/libgambatte/src/cinterface.cpp b/libgambatte/src/cinterface.cpp
index fc4d793a75..ad8247f17c 100644
--- a/libgambatte/src/cinterface.cpp
+++ b/libgambatte/src/cinterface.cpp
@@ -85,17 +85,17 @@ GBEXPORT void gambatte_setinputgetter(GB *g, unsigned (*getinput)(void))
g->setInputGetter(getinput);
}
-GBEXPORT void gambatte_setreadcallback(GB *g, void (*callback)(unsigned))
+GBEXPORT void gambatte_setreadcallback(GB *g, MemoryCallback callback)
{
g->setReadCallback(callback);
}
-GBEXPORT void gambatte_setwritecallback(GB *g, void (*callback)(unsigned))
+GBEXPORT void gambatte_setwritecallback(GB *g, MemoryCallback callback)
{
g->setWriteCallback(callback);
}
-GBEXPORT void gambatte_setexeccallback(GB *g, void (*callback)(unsigned))
+GBEXPORT void gambatte_setexeccallback(GB *g, MemoryCallback callback)
{
g->setExecCallback(callback);
}
diff --git a/libgambatte/src/cpu.cpp b/libgambatte/src/cpu.cpp
index 0fcebe0ca6..3db9a3c7c0 100644
--- a/libgambatte/src/cpu.cpp
+++ b/libgambatte/src/cpu.cpp
@@ -45,6 +45,7 @@ CPU::CPU()
}
long CPU::runFor(const unsigned long cycles) {
+ memory.setBasetime(cycleCounter_);
process(cycles/* << memory.isDoubleSpeed()*/);
const long csb = memory.cyclesSinceBlit(cycleCounter_);
diff --git a/libgambatte/src/cpu.h b/libgambatte/src/cpu.h
index 46dc592015..427847e95d 100644
--- a/libgambatte/src/cpu.h
+++ b/libgambatte/src/cpu.h
@@ -72,15 +72,15 @@ public:
memory.setInputGetter(getInput);
}
- void setReadCallback(void (*callback)(unsigned)) {
+ void setReadCallback(MemoryCallback callback) {
memory.setReadCallback(callback);
}
- void setWriteCallback(void (*callback)(unsigned)) {
+ void setWriteCallback(MemoryCallback callback) {
memory.setWriteCallback(callback);
}
- void setExecCallback(void (*callback)(unsigned)) {
+ void setExecCallback(MemoryCallback callback) {
memory.setExecCallback(callback);
}
diff --git a/libgambatte/src/gambatte.cpp b/libgambatte/src/gambatte.cpp
index 167e1093e1..a1e3dfa65c 100644
--- a/libgambatte/src/gambatte.cpp
+++ b/libgambatte/src/gambatte.cpp
@@ -108,15 +108,15 @@ void GB::setInputGetter(unsigned (*getInput)()) {
p_->cpu.setInputGetter(getInput);
}
-void GB::setReadCallback(void (*callback)(unsigned)) {
+void GB::setReadCallback(MemoryCallback callback) {
p_->cpu.setReadCallback(callback);
}
-void GB::setWriteCallback(void (*callback)(unsigned)) {
+void GB::setWriteCallback(MemoryCallback callback) {
p_->cpu.setWriteCallback(callback);
}
-void GB::setExecCallback(void (*callback)(unsigned)) {
+void GB::setExecCallback(MemoryCallback callback) {
p_->cpu.setExecCallback(callback);
}
diff --git a/libgambatte/src/memory.h b/libgambatte/src/memory.h
index 95a2e18f16..ac2b5d2d17 100644
--- a/libgambatte/src/memory.h
+++ b/libgambatte/src/memory.h
@@ -44,10 +44,11 @@ class Memory {
bool gbIsCgb_;
unsigned short &SP;
unsigned short &PC;
+ unsigned long basetime;
- void (*readCallback)(unsigned);
- void (*writeCallback)(unsigned);
- void (*execCallback)(unsigned);
+ MemoryCallback readCallback;
+ MemoryCallback writeCallback;
+ MemoryCallback execCallback;
CDCallback cdCallback;
void(*linkCallback)();
@@ -134,6 +135,8 @@ public:
void di() { intreq.di(); }
unsigned ff_read(const unsigned P, const unsigned long cycleCounter) {
+ if (readCallback)
+ readCallback(P, (cycleCounter - basetime) >> 1);
return P < 0xFF80 ? nontrivial_ff_read(P, cycleCounter) : ioamhram[P - 0xFE00];
}
@@ -206,7 +209,7 @@ public:
unsigned read(const unsigned P, const unsigned long cycleCounter) {
if (readCallback)
- readCallback(P);
+ readCallback(P, (cycleCounter - basetime) >> 1);
if(cdCallback)
{
CDMapResult map = CDMap(P);
@@ -221,7 +224,7 @@ public:
unsigned read_excb(const unsigned P, const unsigned long cycleCounter, bool first) {
if (execCallback)
- execCallback(P);
+ execCallback(P, (cycleCounter - basetime) >> 1);
if(cdCallback)
{
CDMapResult map = CDMap(P);
@@ -254,7 +257,7 @@ public:
} else
nontrivial_write(P, data, cycleCounter);
if (writeCallback)
- writeCallback(P);
+ writeCallback(P, (cycleCounter - basetime) >> 1);
if(cdCallback)
{
CDMapResult map = CDMap(P);
@@ -268,6 +271,8 @@ public:
ioamhram[P - 0xFE00] = data;
} else
nontrivial_ff_write(P, data, cycleCounter);
+ if (writeCallback)
+ writeCallback(P, (cycleCounter - basetime) >> 1);
if(cdCallback)
{
CDMapResult map = CDMap(P);
@@ -285,13 +290,13 @@ public:
this->getInput = getInput;
}
- void setReadCallback(void (*callback)(unsigned)) {
+ void setReadCallback(MemoryCallback callback) {
this->readCallback = callback;
}
- void setWriteCallback(void (*callback)(unsigned)) {
+ void setWriteCallback(MemoryCallback callback) {
this->writeCallback = callback;
}
- void setExecCallback(void (*callback)(unsigned)) {
+ void setExecCallback(MemoryCallback callback) {
this->execCallback = callback;
}
void setCDCallback(CDCallback cdc) {
@@ -310,6 +315,7 @@ public:
this->linkCallback = callback;
}
+ void setBasetime(unsigned long cc) { basetime = cc; }
void setEndtime(unsigned long cc, unsigned long inc);
void setSoundBuffer(uint_least32_t *const buf) { sound.setBuffer(buf); }
diff --git a/output/dll/libgambatte.dll b/output/dll/libgambatte.dll
index 20e9164416..4c02731caf 100644
Binary files a/output/dll/libgambatte.dll and b/output/dll/libgambatte.dll differ