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 "core/core.h"
|
||||
#include "util/crc32.h"
|
||||
#include "util/memory.h"
|
||||
#include "util/math.h"
|
||||
|
|
|
@ -47,7 +47,7 @@ struct GB {
|
|||
struct GBVideo video;
|
||||
struct GBTimer timer;
|
||||
|
||||
int* keySource;
|
||||
uint8_t* keySource;
|
||||
|
||||
void* pristineRom;
|
||||
size_t pristineRomSize;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue