all repos — mgba @ 7c087d5cb9ae92abcc62cdc06321344ddab0e295

mGBA Game Boy Advance Emulator

Core: Start adding mCore
Jeffrey Pfau jeffrey@endrift.com
Wed, 27 Jan 2016 01:05:12 -0800
commit

7c087d5cb9ae92abcc62cdc06321344ddab0e295

parent

fc0109282b81c5fac6a108b4636192d8efe2b345

A src/gb/core.c

@@ -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; +}
A src/gb/core.h

@@ -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
M src/gb/gb.csrc/gb/gb.c

@@ -7,6 +7,7 @@ #include "gb.h"

#include "gb/io.h" +#include "core/core.h" #include "util/crc32.h" #include "util/memory.h" #include "util/math.h"
M src/gb/gb.hsrc/gb/gb.h

@@ -47,7 +47,7 @@ struct GBMemory memory;

struct GBVideo video; struct GBTimer timer; - int* keySource; + uint8_t* keySource; void* pristineRom; size_t pristineRomSize;
M src/lr35902/lr35902.csrc/lr35902/lr35902.c

@@ -93,7 +93,7 @@ cpu->instruction = _LR35902InstructionIRQFinish;

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 @@ break;

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); +}
M src/lr35902/lr35902.hsrc/lr35902/lr35902.h

@@ -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
M src/platform/sdl/gl-sdl.csrc/platform/sdl/gl-sdl.c

@@ -7,8 +7,12 @@ #include "main.h"

#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 @@ return true;

} 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 @@ renderer->player.windowUpdated = 0;

} #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
M src/platform/sdl/main.csrc/platform/sdl/main.c

@@ -13,6 +13,7 @@ #ifdef USE_GDB_STUB

#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/supervisor/thread.h"

#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 @@ }

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 @@ GBAConfigDeinit(&config);

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 @@ #endif

#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 @@ snprintf(savepath, sizeof(savepath), "%s" PATH_SEP "%s.sav", dirname, basename);

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; }
M src/platform/sdl/main.hsrc/platform/sdl/main.h

@@ -40,15 +40,14 @@ #ifdef USE_PIXMAN

#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;