GB Video: Frame end callback should only happen on instruction boundary
Jeffrey Pfau jeffrey@endrift.com
Sat, 28 May 2016 10:50:17 -0700
2 files changed,
21 insertions(+),
4 deletions(-)
M
src/gb/video.c
→
src/gb/video.c
@@ -50,6 +50,7 @@ video->eventDiff = 0;
video->nextMode = INT_MAX; video->dotCounter = INT_MIN; + video->nextFrame = INT_MAX; video->frameCounter = 0; video->frameskipCounter = 0;@@ -88,6 +89,7 @@ }
if (video->nextEvent <= 0) { if (video->nextEvent != INT_MAX) { video->nextMode -= video->eventDiff; + video->nextFrame -= video->eventDiff; } video->nextEvent = INT_MAX; GBVideoProcessDots(video);@@ -116,12 +118,10 @@ video->renderer->finishFrame(video->renderer);
mCoreSyncPostFrame(video->p->sync); video->frameskipCounter = video->frameskip; } - GBFrameEnded(video->p); ++video->frameCounter; - struct mCoreThread* thread = mCoreThreadGet(); - if (thread && thread->frameCallback) { - thread->frameCallback(thread); + if (video->nextFrame != 0) { + video->nextFrame = 0; } if (video->p->stream && video->p->stream->postVideoFrame) {@@ -197,6 +197,21 @@ break;
} video->stat = GBRegisterSTATSetMode(video->stat, video->mode); video->p->memory.io[REG_STAT] = video->stat; + } + if (video->nextFrame <= 0) { + if (video->p->cpu->executionState == LR35902_CORE_FETCH) { + GBFrameEnded(video->p); + struct mCoreThread* thread = mCoreThreadGet(); + if (thread && thread->frameCallback) { + thread->frameCallback(thread); + } + video->nextFrame = GB_VIDEO_TOTAL_LENGTH; + } else { + video->nextFrame = 4 - ((video->p->cpu->executionState + 1) & 3); + if (video->nextFrame < video->nextEvent) { + video->nextEvent = video->nextFrame; + } + } } if (video->nextMode < video->nextEvent) { video->nextEvent = video->nextMode;
M
src/gb/video.h
→
src/gb/video.h
@@ -104,6 +104,8 @@
int32_t nextMode; int32_t dotCounter; + int32_t nextFrame; + uint8_t* vram; uint8_t* vramBank; int vramCurrentBank;