mirror of https://github.com/mgba-emu/mgba.git
Core: Start adding mCore
This commit is contained in:
parent
fc0109282b
commit
7c087d5cb9
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue