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 "core/core.h"
#include "util/crc32.h"
#include "util/memory.h"
#include "util/math.h"

View File

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

View File

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

View File

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

View File

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

View File

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