Gambatte: implement TotalExecutedCycles
This commit is contained in:
parent
fde2035f31
commit
f968cbdd73
|
@ -44,19 +44,35 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
[FeatureNotImplemented]
|
|
||||||
public int TotalExecutedCycles
|
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;
|
public IMemoryCallbackSystem MemoryCallbacks => _memorycallbacks;
|
||||||
|
|
||||||
private LibGambatte.MemoryCallback _readcb;
|
private LibGambatte.MemoryCallback _readcb;
|
||||||
private LibGambatte.MemoryCallback _writecb;
|
private LibGambatte.MemoryCallback _writecb;
|
||||||
private LibGambatte.MemoryCallback _execcb;
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// for use in dual core
|
/// for use in dual core
|
||||||
|
@ -68,9 +84,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
|
|
||||||
private void InitMemoryCallbacks()
|
private void InitMemoryCallbacks()
|
||||||
{
|
{
|
||||||
_readcb = addr => MemoryCallbacks.CallReads(addr, "System Bus");
|
_readcb = new LibGambatte.MemoryCallback(ReadCallback);
|
||||||
_writecb = addr => MemoryCallbacks.CallWrites(addr, "System Bus");
|
_writecb = new LibGambatte.MemoryCallback(WriteCallback);
|
||||||
_execcb = addr => MemoryCallbacks.CallExecutes(addr, "System Bus");
|
_execcb = new LibGambatte.MemoryCallback(ExecCallback);
|
||||||
_memorycallbacks.ActiveChanged += RefreshMemoryCallbacks;
|
_memorycallbacks.ActiveChanged += RefreshMemoryCallbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -244,6 +244,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
/// total cycles actually executed
|
/// total cycles actually executed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private ulong _cycleCount = 0;
|
private ulong _cycleCount = 0;
|
||||||
|
private ulong callbackCycleCount = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// number of extra cycles we overran in the last frame
|
/// number of extra cycles we overran in the last frame
|
||||||
|
|
|
@ -190,7 +190,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="address">the address which the cpu is read\writing</param>
|
/// <param name="address">the address which the cpu is read\writing</param>
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
public delegate void MemoryCallback(uint address);
|
public delegate void MemoryCallback(uint address, ulong cycleOffset);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// type of the CDLogger callback
|
/// type of the CDLogger callback
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
namespace gambatte {
|
namespace gambatte {
|
||||||
enum { BG_PALETTE = 0, SP1_PALETTE = 1, SP2_PALETTE = 2 };
|
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);
|
typedef void (*CDCallback)(int32_t addr, int32_t addrtype, int32_t flags);
|
||||||
|
|
||||||
enum eCDLog_AddrType
|
enum eCDLog_AddrType
|
||||||
|
@ -105,9 +106,9 @@ public:
|
||||||
/** Sets the callback used for getting input state. */
|
/** Sets the callback used for getting input state. */
|
||||||
void setInputGetter(unsigned (*getInput)());
|
void setInputGetter(unsigned (*getInput)());
|
||||||
|
|
||||||
void setReadCallback(void (*callback)(unsigned));
|
void setReadCallback(MemoryCallback);
|
||||||
void setWriteCallback(void (*callback)(unsigned));
|
void setWriteCallback(MemoryCallback);
|
||||||
void setExecCallback(void (*callback)(unsigned));
|
void setExecCallback(MemoryCallback);
|
||||||
void setCDCallback(CDCallback);
|
void setCDCallback(CDCallback);
|
||||||
void setTraceCallback(void (*callback)(void *));
|
void setTraceCallback(void (*callback)(void *));
|
||||||
void setScanlineCallback(void (*callback)(), int sl);
|
void setScanlineCallback(void (*callback)(), int sl);
|
||||||
|
|
|
@ -85,17 +85,17 @@ GBEXPORT void gambatte_setinputgetter(GB *g, unsigned (*getinput)(void))
|
||||||
g->setInputGetter(getinput);
|
g->setInputGetter(getinput);
|
||||||
}
|
}
|
||||||
|
|
||||||
GBEXPORT void gambatte_setreadcallback(GB *g, void (*callback)(unsigned))
|
GBEXPORT void gambatte_setreadcallback(GB *g, MemoryCallback callback)
|
||||||
{
|
{
|
||||||
g->setReadCallback(callback);
|
g->setReadCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
GBEXPORT void gambatte_setwritecallback(GB *g, void (*callback)(unsigned))
|
GBEXPORT void gambatte_setwritecallback(GB *g, MemoryCallback callback)
|
||||||
{
|
{
|
||||||
g->setWriteCallback(callback);
|
g->setWriteCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
GBEXPORT void gambatte_setexeccallback(GB *g, void (*callback)(unsigned))
|
GBEXPORT void gambatte_setexeccallback(GB *g, MemoryCallback callback)
|
||||||
{
|
{
|
||||||
g->setExecCallback(callback);
|
g->setExecCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ CPU::CPU()
|
||||||
}
|
}
|
||||||
|
|
||||||
long CPU::runFor(const unsigned long cycles) {
|
long CPU::runFor(const unsigned long cycles) {
|
||||||
|
memory.setBasetime(cycleCounter_);
|
||||||
process(cycles/* << memory.isDoubleSpeed()*/);
|
process(cycles/* << memory.isDoubleSpeed()*/);
|
||||||
|
|
||||||
const long csb = memory.cyclesSinceBlit(cycleCounter_);
|
const long csb = memory.cyclesSinceBlit(cycleCounter_);
|
||||||
|
|
|
@ -72,15 +72,15 @@ public:
|
||||||
memory.setInputGetter(getInput);
|
memory.setInputGetter(getInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setReadCallback(void (*callback)(unsigned)) {
|
void setReadCallback(MemoryCallback callback) {
|
||||||
memory.setReadCallback(callback);
|
memory.setReadCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWriteCallback(void (*callback)(unsigned)) {
|
void setWriteCallback(MemoryCallback callback) {
|
||||||
memory.setWriteCallback(callback);
|
memory.setWriteCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setExecCallback(void (*callback)(unsigned)) {
|
void setExecCallback(MemoryCallback callback) {
|
||||||
memory.setExecCallback(callback);
|
memory.setExecCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,15 +108,15 @@ void GB::setInputGetter(unsigned (*getInput)()) {
|
||||||
p_->cpu.setInputGetter(getInput);
|
p_->cpu.setInputGetter(getInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GB::setReadCallback(void (*callback)(unsigned)) {
|
void GB::setReadCallback(MemoryCallback callback) {
|
||||||
p_->cpu.setReadCallback(callback);
|
p_->cpu.setReadCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GB::setWriteCallback(void (*callback)(unsigned)) {
|
void GB::setWriteCallback(MemoryCallback callback) {
|
||||||
p_->cpu.setWriteCallback(callback);
|
p_->cpu.setWriteCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GB::setExecCallback(void (*callback)(unsigned)) {
|
void GB::setExecCallback(MemoryCallback callback) {
|
||||||
p_->cpu.setExecCallback(callback);
|
p_->cpu.setExecCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,10 +44,11 @@ class Memory {
|
||||||
bool gbIsCgb_;
|
bool gbIsCgb_;
|
||||||
unsigned short &SP;
|
unsigned short &SP;
|
||||||
unsigned short &PC;
|
unsigned short &PC;
|
||||||
|
unsigned long basetime;
|
||||||
|
|
||||||
void (*readCallback)(unsigned);
|
MemoryCallback readCallback;
|
||||||
void (*writeCallback)(unsigned);
|
MemoryCallback writeCallback;
|
||||||
void (*execCallback)(unsigned);
|
MemoryCallback execCallback;
|
||||||
CDCallback cdCallback;
|
CDCallback cdCallback;
|
||||||
void(*linkCallback)();
|
void(*linkCallback)();
|
||||||
|
|
||||||
|
@ -134,6 +135,8 @@ public:
|
||||||
void di() { intreq.di(); }
|
void di() { intreq.di(); }
|
||||||
|
|
||||||
unsigned ff_read(const unsigned P, const unsigned long cycleCounter) {
|
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];
|
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) {
|
unsigned read(const unsigned P, const unsigned long cycleCounter) {
|
||||||
if (readCallback)
|
if (readCallback)
|
||||||
readCallback(P);
|
readCallback(P, (cycleCounter - basetime) >> 1);
|
||||||
if(cdCallback)
|
if(cdCallback)
|
||||||
{
|
{
|
||||||
CDMapResult map = CDMap(P);
|
CDMapResult map = CDMap(P);
|
||||||
|
@ -221,7 +224,7 @@ public:
|
||||||
|
|
||||||
unsigned read_excb(const unsigned P, const unsigned long cycleCounter, bool first) {
|
unsigned read_excb(const unsigned P, const unsigned long cycleCounter, bool first) {
|
||||||
if (execCallback)
|
if (execCallback)
|
||||||
execCallback(P);
|
execCallback(P, (cycleCounter - basetime) >> 1);
|
||||||
if(cdCallback)
|
if(cdCallback)
|
||||||
{
|
{
|
||||||
CDMapResult map = CDMap(P);
|
CDMapResult map = CDMap(P);
|
||||||
|
@ -254,7 +257,7 @@ public:
|
||||||
} else
|
} else
|
||||||
nontrivial_write(P, data, cycleCounter);
|
nontrivial_write(P, data, cycleCounter);
|
||||||
if (writeCallback)
|
if (writeCallback)
|
||||||
writeCallback(P);
|
writeCallback(P, (cycleCounter - basetime) >> 1);
|
||||||
if(cdCallback)
|
if(cdCallback)
|
||||||
{
|
{
|
||||||
CDMapResult map = CDMap(P);
|
CDMapResult map = CDMap(P);
|
||||||
|
@ -268,6 +271,8 @@ public:
|
||||||
ioamhram[P - 0xFE00] = data;
|
ioamhram[P - 0xFE00] = data;
|
||||||
} else
|
} else
|
||||||
nontrivial_ff_write(P, data, cycleCounter);
|
nontrivial_ff_write(P, data, cycleCounter);
|
||||||
|
if (writeCallback)
|
||||||
|
writeCallback(P, (cycleCounter - basetime) >> 1);
|
||||||
if(cdCallback)
|
if(cdCallback)
|
||||||
{
|
{
|
||||||
CDMapResult map = CDMap(P);
|
CDMapResult map = CDMap(P);
|
||||||
|
@ -285,13 +290,13 @@ public:
|
||||||
this->getInput = getInput;
|
this->getInput = getInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setReadCallback(void (*callback)(unsigned)) {
|
void setReadCallback(MemoryCallback callback) {
|
||||||
this->readCallback = callback;
|
this->readCallback = callback;
|
||||||
}
|
}
|
||||||
void setWriteCallback(void (*callback)(unsigned)) {
|
void setWriteCallback(MemoryCallback callback) {
|
||||||
this->writeCallback = callback;
|
this->writeCallback = callback;
|
||||||
}
|
}
|
||||||
void setExecCallback(void (*callback)(unsigned)) {
|
void setExecCallback(MemoryCallback callback) {
|
||||||
this->execCallback = callback;
|
this->execCallback = callback;
|
||||||
}
|
}
|
||||||
void setCDCallback(CDCallback cdc) {
|
void setCDCallback(CDCallback cdc) {
|
||||||
|
@ -310,6 +315,7 @@ public:
|
||||||
this->linkCallback = callback;
|
this->linkCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setBasetime(unsigned long cc) { basetime = cc; }
|
||||||
void setEndtime(unsigned long cc, unsigned long inc);
|
void setEndtime(unsigned long cc, unsigned long inc);
|
||||||
|
|
||||||
void setSoundBuffer(uint_least32_t *const buf) { sound.setBuffer(buf); }
|
void setSoundBuffer(uint_least32_t *const buf) { sound.setBuffer(buf); }
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue