Core: Start adding mCore

This commit is contained in:
Jeffrey Pfau 2016-01-27 01:05:12 -08:00
parent fc0109282b
commit 7c087d5cb9
9 changed files with 175 additions and 33 deletions

119
src/gb/core.c Normal file
View File

@ -0,0 +1,119 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "core.h"
#include "core/core.h"
#include "gb/gb.h"
#include "gb/renderers/software.h"
#include "util/memory.h"
struct GBCore {
struct mCore d;
struct GBVideoSoftwareRenderer renderer;
uint8_t keys;
};
static bool _GBCoreInit(struct mCore* core) {
struct GBCore* gbcore = (struct GBCore*) core;
struct LR35902Core* cpu = anonymousMemoryMap(sizeof(struct LR35902Core));
struct GB* gb = anonymousMemoryMap(sizeof(struct GB));
if (!cpu || !gb) {
free(cpu);
free(gb);
return false;
}
core->cpu = cpu;
core->board = gb;
GBCreate(gb);
LR35902SetComponents(cpu, &gb->d, 0, 0);
LR35902Init(cpu);
GBVideoSoftwareRendererCreate(&gbcore->renderer);
GBVideoAssociateRenderer(&gb->video, &gbcore->renderer.d);
gb->keySource = &gbcore->keys;
return true;
}
static void _GBCoreDeinit(struct mCore* core) {
LR35902Deinit(core->cpu);
GBDestroy(core->board);
mappedMemoryFree(core->cpu, sizeof(struct LR35902Core));
mappedMemoryFree(core->board, sizeof(struct GB));
}
static void _GBCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {
UNUSED(core);
*width = GB_VIDEO_HORIZONTAL_PIXELS;
*height = GB_VIDEO_VERTICAL_PIXELS;
}
static void _GBCoreSetVideoBuffer(struct mCore* core, void* buffer, size_t stride) {
struct GBCore* gbcore = (struct GBCore*) core;
gbcore->renderer.outputBuffer = buffer;
gbcore->renderer.outputBufferStride = stride;
}
static bool _GBCoreLoadROM(struct mCore* core, struct VFile* vf, struct VFile* save, const char* fname) {
return GBLoadROM(core->board, vf, save, fname);
}
static bool _GBCoreIsROM(struct mCore* core, struct VFile* vf) {
UNUSED(core);
return GBIsROM(vf);
}
static void _GBCoreUnloadROM(struct mCore* core) {
return GBUnloadROM(core->board);
}
static void _GBCoreReset(struct mCore* core) {
LR35902Reset(core->cpu);
}
static void _GBCoreRunFrame(struct mCore* core) {
struct GB* gb = core->board;
int32_t frameCounter = gb->video.frameCounter;
while (gb->video.frameCounter == frameCounter) {
LR35902Run(core->cpu);
}
}
static void _GBCoreRunLoop(struct mCore* core) {
LR35902Run(core->cpu);
}
static void _GBCoreStep(struct mCore* core) {
LR35902Tick(core->cpu);
}
static void _GBCoreSetKeys(struct mCore* core, uint32_t keys) {
struct GBCore* gbcore = (struct GBCore*) core;
gbcore->keys = keys;
}
struct mCore* GBCoreCreate(void) {
struct GBCore* gbcore = malloc(sizeof(*gbcore));
struct mCore* core = &gbcore->d;
core->cpu = 0;
core->board = 0;
core->init = _GBCoreInit;
core->deinit = _GBCoreDeinit;
core->desiredVideoDimensions = _GBCoreDesiredVideoDimensions;
core->setVideoBuffer = _GBCoreSetVideoBuffer;
core->isROM = _GBCoreIsROM;
core->loadROM = _GBCoreLoadROM;
core->unloadROM = _GBCoreUnloadROM;
core->reset = _GBCoreReset;
core->runFrame = _GBCoreRunFrame;
core->runLoop = _GBCoreRunLoop;
core->step = _GBCoreStep;
core->setKeys = _GBCoreSetKeys;
return core;
}

12
src/gb/core.h Normal file
View File

@ -0,0 +1,12 @@
/* Copyright (c) 2013-2016 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GB_CORE_H
#define GB_CORE_H
struct mCore;
struct mCore* GBCoreCreate(void);
#endif

View File

@ -7,6 +7,7 @@
#include "gb/io.h" #include "gb/io.h"
#include "core/core.h"
#include "util/crc32.h" #include "util/crc32.h"
#include "util/memory.h" #include "util/memory.h"
#include "util/math.h" #include "util/math.h"

View File

@ -47,7 +47,7 @@ struct GB {
struct GBVideo video; struct GBVideo video;
struct GBTimer timer; struct GBTimer timer;
int* keySource; uint8_t* keySource;
void* pristineRom; void* pristineRom;
size_t pristineRomSize; size_t pristineRomSize;

View File

@ -93,7 +93,7 @@ static void _LR35902InstructionIRQ(struct LR35902Core* cpu) {
cpu->irqh.setInterrupts(cpu, false); cpu->irqh.setInterrupts(cpu, false);
} }
void LR35902Tick(struct LR35902Core* cpu) { static void _lr35902Step(struct LR35902Core* cpu) {
++cpu->cycles; ++cpu->cycles;
enum LR35902ExecutionState state = cpu->executionState; enum LR35902ExecutionState state = cpu->executionState;
++cpu->executionState; ++cpu->executionState;
@ -129,7 +129,18 @@ void LR35902Tick(struct LR35902Core* cpu) {
default: default:
break; break;
} }
}
void LR35902Tick(struct LR35902Core* cpu) {
_lr35902Step(cpu);
if (cpu->cycles >= cpu->nextEvent) { if (cpu->cycles >= cpu->nextEvent) {
cpu->irqh.processEvents(cpu); cpu->irqh.processEvents(cpu);
} }
} }
void LR35902Run(struct LR35902Core* cpu) {
while (cpu->cycles < cpu->nextEvent) {
_lr35902Step(cpu);
}
cpu->irqh.processEvents(cpu);
}

View File

@ -171,5 +171,6 @@ void LR35902Reset(struct LR35902Core* cpu);
void LR35902RaiseIRQ(struct LR35902Core* cpu, uint8_t vector); void LR35902RaiseIRQ(struct LR35902Core* cpu, uint8_t vector);
void LR35902Tick(struct LR35902Core* cpu); void LR35902Tick(struct LR35902Core* cpu);
void LR35902Run(struct LR35902Core* cpu);
#endif #endif

View File

@ -7,8 +7,12 @@
#include "gl-common.h" #include "gl-common.h"
#include "core/core.h"
#ifdef M_CORE_GBA
#include "gba/supervisor/thread.h" #include "gba/supervisor/thread.h"
#endif
#ifdef M_CORE_GB #ifdef M_CORE_GB
#include "gb/core.h"
#include "gb/gb.h" #include "gb/gb.h"
#endif #endif
#include "platform/opengl/gl.h" #include "platform/opengl/gl.h"
@ -106,10 +110,9 @@ bool mSDLGLInitGB(struct mSDLRenderer* renderer) {
mSDLGLCommonInit(renderer); mSDLGLCommonInit(renderer);
// TODO: Pass texture size along // TODO: Pass texture size along
color_t* buf = malloc(VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL); renderer->outputBuffer = malloc(VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
memset(buf, 0, VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL); memset(renderer->outputBuffer, 0, VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
renderer->gb.outputBuffer = buf + GB_GBA_CENTER; renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer + GB_GBA_CENTER, VIDEO_HORIZONTAL_PIXELS);
renderer->gb.outputBufferStride = VIDEO_HORIZONTAL_PIXELS;
GBAGLContextCreate(&renderer->gl); GBAGLContextCreate(&renderer->gl);
renderer->gl.d.user = renderer; renderer->gl.d.user = renderer;
@ -123,17 +126,13 @@ bool mSDLGLInitGB(struct mSDLRenderer* renderer) {
} }
void mSDLGLRunloopGB(struct mSDLRenderer* renderer, void* user) { void mSDLGLRunloopGB(struct mSDLRenderer* renderer, void* user) {
struct GB* gb = user; UNUSED(user);
SDL_Event event; SDL_Event event;
struct VideoBackend* v = &renderer->gl.d; struct VideoBackend* v = &renderer->gl.d;
int activeKeys = 0; int activeKeys = 0;
gb->keySource = &activeKeys;
while (true) { while (true) {
int64_t frameCounter = gb->video.frameCounter; renderer->core->runFrame(renderer->core);
while (gb->video.frameCounter == frameCounter) {
LR35902Tick(gb->cpu);
}
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
// TODO: Refactor out // TODO: Refactor out
if (event.type == SDL_KEYUP || event.type == SDL_KEYDOWN) { if (event.type == SDL_KEYUP || event.type == SDL_KEYDOWN) {
@ -164,8 +163,9 @@ void mSDLGLRunloopGB(struct mSDLRenderer* renderer, void* user) {
} }
#endif #endif
} }
renderer->core->setKeys(renderer->core, activeKeys);
v->postFrame(v, renderer->gb.outputBuffer - GB_GBA_CENTER); v->postFrame(v, renderer->outputBuffer);
v->drawFrame(v); v->drawFrame(v);
v->swap(v); v->swap(v);
} }
@ -175,7 +175,7 @@ void mSDLGLDeinitGB(struct mSDLRenderer* renderer) {
if (renderer->gl.d.deinit) { if (renderer->gl.d.deinit) {
renderer->gl.d.deinit(&renderer->gl.d); renderer->gl.d.deinit(&renderer->gl.d);
} }
free(renderer->gb.outputBuffer - GB_GBA_CENTER); free(renderer->outputBuffer);
#if SDL_VERSION_ATLEAST(2, 0, 0) #if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GL_DeleteContext(renderer->glCtx); SDL_GL_DeleteContext(renderer->glCtx);
#endif #endif

View File

@ -13,6 +13,7 @@
#include "debugger/gdb-stub.h" #include "debugger/gdb-stub.h"
#endif #endif
#include "core/core.h"
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
#include "gba/gba.h" #include "gba/gba.h"
#include "gba/context/config.h" #include "gba/context/config.h"
@ -20,6 +21,7 @@
#include "gba/video.h" #include "gba/video.h"
#endif #endif
#ifdef M_CORE_GB #ifdef M_CORE_GB
#include "gb/core.h"
#include "gb/gb.h" #include "gb/gb.h"
#include "gb/video.h" #include "gb/video.h"
#endif #endif
@ -135,7 +137,7 @@ int main(int argc, char** argv) {
if (!opts.height) { if (!opts.height) {
opts.height = /*GB_*/VIDEO_VERTICAL_PIXELS; opts.height = /*GB_*/VIDEO_VERTICAL_PIXELS;
} }
GBVideoSoftwareRendererCreate(&renderer.gb); renderer.core = GBCoreCreate();
#ifdef BUILD_GL #ifdef BUILD_GL
mSDLGLCreateGB(&renderer); mSDLGLCreateGB(&renderer);
#elif defined(BUILD_GLES2) || defined(USE_EPOXY) #elif defined(BUILD_GLES2) || defined(USE_EPOXY)
@ -180,6 +182,11 @@ int main(int argc, char** argv) {
return 1; return 1;
} }
if (renderer.core) {
// TODO: Check return code
renderer.core->init(renderer.core);
}
renderer.player.bindings = &inputMap; renderer.player.bindings = &inputMap;
GBASDLInitBindings(&inputMap); GBASDLInitBindings(&inputMap);
GBASDLInitEvents(&renderer.events); GBASDLInitEvents(&renderer.events);
@ -268,14 +275,6 @@ int mSDLRunGBA(struct mSDLRenderer* renderer, struct GBAArguments* args, struct
#ifdef M_CORE_GB #ifdef M_CORE_GB
int mSDLRunGB(struct mSDLRenderer* renderer, struct GBAArguments* args) { int mSDLRunGB(struct mSDLRenderer* renderer, struct GBAArguments* args) {
struct LR35902Core cpu;
struct GB gb;
GBCreate(&gb);
LR35902SetComponents(&cpu, &gb.d, 0, 0);
LR35902Init(&cpu);
GBVideoAssociateRenderer(&gb.video, &renderer->gb.d);
struct VFile* vf = VFileOpen(args->fname, O_RDONLY); struct VFile* vf = VFileOpen(args->fname, O_RDONLY);
struct VFile* savVf = 0; struct VFile* savVf = 0;
@ -288,10 +287,10 @@ int mSDLRunGB(struct mSDLRenderer* renderer, struct GBAArguments* args) {
savVf = VFileOpen(savepath, O_RDWR | O_CREAT); savVf = VFileOpen(savepath, O_RDWR | O_CREAT);
} }
GBLoadROM(&gb, vf, savVf, args->fname); renderer->core->loadROM(renderer->core, vf, savVf, args->fname);
renderer->core->reset(renderer->core);
LR35902Reset(&cpu); renderer->runloop(renderer, NULL);
renderer->runloop(renderer, &gb); renderer->core->unloadROM(renderer->core);
vf->close(vf); vf->close(vf);
return 0; return 0;
} }

View File

@ -40,15 +40,14 @@
#include <pixman.h> #include <pixman.h>
#endif #endif
struct mCore;
struct mSDLRenderer { struct mSDLRenderer {
union { struct mCore* core;
color_t* outputBuffer;
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
struct GBAVideoSoftwareRenderer d; // TODO: Remove
struct GBAVideoSoftwareRenderer d;
#endif #endif
#ifdef M_CORE_GB
struct GBVideoSoftwareRenderer gb;
#endif
};
struct GBASDLAudio audio; struct GBASDLAudio audio;
struct GBASDLEvents events; struct GBASDLEvents events;
struct GBASDLPlayer player; struct GBASDLPlayer player;