Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GBA hardware extensions #2251

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0051c82
Add .vscode to .gitignore
kaisermg5 Jun 30, 2021
cf6d9ef
Added a protoype protocol to use hardware extensions. Made an extensi…
kaisermg5 Jun 30, 2021
9831a24
Update with master.
kaisermg5 Jun 30, 2021
e563a36
Rewrote most of the extensions code to reorganize the IO and change t…
kaisermg5 Jul 4, 2021
7bba0eb
Hardware extensions code cleanup.
kaisermg5 Jul 4, 2021
acc10c3
Fixed bug that allowed to call disabled extensions.
kaisermg5 Jul 10, 2021
7a12e6a
Added command line arguments to enable extensions.
kaisermg5 Jul 10, 2021
36f5879
Added initial hardware extensions serialization support.
kaisermg5 Jul 11, 2021
71e4e6c
Organized hardware extensions code a bit.
kaisermg5 Jul 11, 2021
58450e6
Organized hardware extensions code a bit more...
kaisermg5 Jul 11, 2021
e3d7cad
Moved some hardcoded stuff to a hardware extensions header file.
kaisermg5 Jul 11, 2021
6223cd7
Designed hardware extensions Qt UI. Functionality missing.
kaisermg5 Jul 19, 2021
3b0b9c3
Fixed some bugs that happened after refactoring.
kaisermg5 Jul 19, 2021
77a0db9
Made each extension have its own config key. Made command line args t…
kaisermg5 Jul 19, 2021
cedf69f
Moved hardware extensions settings into enhancements and redesigned UI.
kaisermg5 Jul 20, 2021
b65493b
De-hardcoded some memory regions. And changed an enum to comply with …
kaisermg5 Jul 21, 2021
165e597
Merge branch 'master' of https://github.com/kaisermg5/mgba
kaisermg5 Jul 21, 2021
558a008
Merge branch 'master' into hardware-extensions
kaisermg5 Jul 21, 2021
ece8c5a
Multiple name changes, moved files and other small changes related to…
kaisermg5 Jul 22, 2021
97dac47
Convert spaces indentation to tabs in gab extensions files.
kaisermg5 Jul 22, 2021
274183e
Removed gba extensions command line args. Also removed their optiond …
kaisermg5 Jul 23, 2021
11a7413
Merged extensions-ids.h with extensions.h. And replaced mCore's exten…
kaisermg5 Jul 23, 2021
d89678a
Fixed error on GB, while attempting to deserialize extensions data.
kaisermg5 Jul 25, 2021
b2c2e55
Changes to dynamically alloc GBA extensions IO and extra RAM. Added t…
kaisermg5 Jul 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
/build
/build-*
/.vs
/.vscode

*.a
*.dylib
Expand Down
4 changes: 4 additions & 0 deletions include/mgba/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
CXX_GUARD_START

#include <mgba/core/config.h>
#include <mgba/core/serialize.h>
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
#include <mgba/core/directories.h>
#endif
Expand Down Expand Up @@ -160,6 +161,9 @@ struct mCore {
void (*startVideoLog)(struct mCore*, struct mVideoLogContext*);
void (*endVideoLog)(struct mCore*);
#endif

size_t (*extDataSerialize)(struct mCore*, enum mStateExtdataTag tag, void** sram);
bool (*extDataDeserialize)(struct mCore*, enum mStateExtdataTag tag, const void* sram, size_t size);
};

#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
Expand Down
2 changes: 2 additions & 0 deletions include/mgba/core/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum mStateExtdataTag {
EXTDATA_SAVEDATA = 2,
EXTDATA_CHEATS = 3,
EXTDATA_RTC = 4,
EXTDATA_GBA_EXTENSIONS = 0x80,
EXTDATA_META_TIME = 0x101,
EXTDATA_MAX
};
Expand All @@ -25,6 +26,7 @@ enum mStateExtdataTag {
#define SAVESTATE_CHEATS 4
#define SAVESTATE_RTC 8
#define SAVESTATE_METADATA 16
#define SAVESTATE_GBA_EXTENSIONS 32

struct mStateExtdataItem {
int32_t size;
Expand Down
70 changes: 70 additions & 0 deletions include/mgba/internal/gba/extra/extensions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* Copyright (c) 2013-2021 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 GBA_EXTENSIONS_H
#define GBA_EXTENSIONS_H

#include <mgba-util/common.h>

CXX_GUARD_START

#include <mgba/core/log.h>
#include <mgba/core/timing.h>

#include <mgba/internal/gba/io.h>

#include <mgba-util/memory.h>

enum GBA_EXTENSIONS_IDS {
GBAEX_ID_EXTRA_RAM = 0,
GBAEX_EXTENSIONS_COUNT
};

#define REG_HWEX_VERSION_VALUE GBAEX_EXTENSIONS_COUNT
#define GBAEX_IO_SIZE (REG_HWEX_END - REG_HWEX0_ENABLE)

struct GBAExtensions {
bool globalEnabled;
bool extensionsEnabled[GBAEX_EXTENSIONS_COUNT];
bool userGlobalEnabled;
bool userExtensionsEnabled[GBAEX_EXTENSIONS_COUNT];

// IO:
uint16_t* io;

// Other data
uint8_t* extraRam;
uint32_t extraRamSize;
uint32_t extraRamRealSize;
};

struct GBAExtensionsStateBlockHeader {
uint32_t id;
uint32_t offset;
uint32_t size;
};

struct GBAExtensionsState {
uint32_t version;
uint32_t extensionsBlockCount;

struct GBAExtensionsStateBlockHeader ioBlockHeader;
// More blocks can come after the IO one
};

struct GBA;
void GBAExtensionsInit(struct GBAExtensions* extensions);
void GBAExtensionsReset(struct GBAExtensions* extensions);
void GBAExtensionsDestroy(struct GBAExtensions* extensions);
uint16_t GBAExtensionsIORead(struct GBA* gba, uint32_t address);
uint32_t GBAExtensionsIORead32(struct GBA* gba, uint32_t address);
void GBAExtensionsIOWrite8(struct GBA* gba, uint32_t address, uint8_t value);
void GBAExtensionsIOWrite(struct GBA* gba, uint32_t address, uint16_t value);
size_t GBAExtensionsSerialize(struct GBA* gba, void** sram);
bool GBAExtensionsDeserialize(struct GBA* gba, const struct GBAExtensionsState* state, size_t size);

CXX_GUARD_END

#endif
2 changes: 2 additions & 0 deletions include/mgba/internal/gba/gba.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ CXX_GUARD_START
#include <mgba/internal/gba/audio.h>
#include <mgba/internal/gba/sio.h>
#include <mgba/internal/gba/timer.h>
#include <mgba/internal/gba/extra/extensions.h>

#define GBA_ARM7TDMI_FREQUENCY 0x1000000U

Expand Down Expand Up @@ -70,6 +71,7 @@ struct GBA {
struct GBAVideo video;
struct GBAAudio audio;
struct GBASIO sio;
struct GBAExtensions extensions;

struct mCoreSync* sync;
struct mTiming timing;
Expand Down
21 changes: 21 additions & 0 deletions include/mgba/internal/gba/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,27 @@ enum GBAIORegisters {
REG_DEBUG_STRING = 0xFFF600,
REG_DEBUG_FLAGS = 0xFFF700,
REG_DEBUG_ENABLE = 0xFFF780,

// Extensions
REG_HWEX_ENABLE = 0x400A00,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This base seems arbitrary. How did you choose it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know what to put, so I chose something in the middle. Didn't want to put it at the end so its easy to add more and also didn't want to put it close to the real registers. Any suggestions?

REG_HWEX_VERSION = 0x400A02,

// Extra RAM
REG_HWEX0_ENABLE = 0x400A04,
REG_HWEX0_CNT = 0x400A06,
REG_HWEX0_RET_CODE = 0x400A08,
REG_HWEX0_UNUSED = 0x400A0A,
REG_HWEX0_P0_LO = 0x400A0C, // command
REG_HWEX0_P0_HI = 0x400A0E,
REG_HWEX0_P1_LO = 0x400A10, // index
REG_HWEX0_P1_HI = 0x400A12,
REG_HWEX0_P2_LO = 0x400A14, // data pointer
REG_HWEX0_P2_HI = 0x400A16,
REG_HWEX0_P3_LO = 0x400A18, // size
REG_HWEX0_P3_HI = 0x400A1A,

REG_HWEX_END = 0x400A1C,

};

mLOG_DECLARE_CATEGORY(GBA_IO);
Expand Down
16 changes: 16 additions & 0 deletions src/core/serialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,18 @@ bool mCoreSaveStateNamed(struct mCore* core, struct VFile* vf, int flags) {
mStateExtdataPut(&extdata, EXTDATA_RTC, &item);
}
}
if ((true || flags & SAVESTATE_GBA_EXTENSIONS) && core->extDataSerialize) {
void* sram = NULL;
size_t size = core->extDataSerialize(core, EXTDATA_GBA_EXTENSIONS, &sram);
if (size) {
struct mStateExtdataItem item = {
.size = size,
.data = sram,
.clean = free
};
mStateExtdataPut(&extdata, EXTDATA_GBA_EXTENSIONS, &item);
}
}
#ifdef USE_PNG
if (!(flags & SAVESTATE_SCREENSHOT)) {
#else
Expand Down Expand Up @@ -537,6 +549,10 @@ bool mCoreLoadStateNamed(struct mCore* core, struct VFile* vf, int flags) {
core->rtc.d.deserialize(&core->rtc.d, &item);
}
}
if ((true || flags & SAVESTATE_GBA_EXTENSIONS) && core->extDataDeserialize && mStateExtdataGet(&extdata, EXTDATA_GBA_EXTENSIONS, &item)) {
mLOG(SAVESTATE, INFO, "Loading GBA extensions");
core->extDataDeserialize(core, EXTDATA_GBA_EXTENSIONS, item.data, item.size);
}
mStateExtdataDeinit(&extdata);
return success;
}
Expand Down
9 changes: 9 additions & 0 deletions src/feature/commandline.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,15 @@ void usage(const char* arg0, const char* extraOptions) {
puts(" -p, --patch FILE Apply a specified patch file when running");
puts(" -s, --frameskip N Skip every N frames");
puts(" --version Print version and exit");

puts("\nHardware extensions options:");
puts(" --hw-extensions Enable hardware extensions");
puts(" --no-hw-extensions Disable hardware extensions");
puts(" --hwex-all Enable all hardware extensions");
puts(" --hwex-none Disable all hardware extensions");
puts(" --hwex-more-ram Enable hardware extension \"More RAM\"");
puts(" --no-hwex-more-ram Disable hardware extension \"More RAM\"");

Comment on lines +252 to +259
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also removed this.

if (extraOptions) {
puts(extraOptions);
}
Expand Down
2 changes: 2 additions & 0 deletions src/gb/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,8 @@ struct mCore* GBCoreCreate(void) {
core->startVideoLog = _GBCoreStartVideoLog;
core->endVideoLog = _GBCoreEndVideoLog;
#endif
core->extDataSerialize = NULL;
core->extDataDeserialize = NULL;
return core;
}

Expand Down
1 change: 1 addition & 0 deletions src/gba/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(SOURCE_FILES
cheats/parv3.c
core.c
dma.c
extra/extensions.c
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extras go in the EXTRA_FILES section below, but the feature will need to be able to be ifdef'd out for that to work.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I ifdef'd under MINIMAL_CORE or do I create a new define?

gba.c
hle-bios.c
input.c
Expand Down
41 changes: 41 additions & 0 deletions src/gba/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,13 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con
#endif
mCoreConfigCopyValue(&core->config, config, "hwaccelVideo");
mCoreConfigCopyValue(&core->config, config, "videoScale");

if (mCoreConfigGetIntValue(config, "gba.extensions", &fakeBool)) {
gba->extensions.userGlobalEnabled = fakeBool;
}
if (mCoreConfigGetIntValue(config, "gba.ext.extraRam", &fakeBool)) {
gba->extensions.userExtensionsEnabled[GBAEX_ID_EXTRA_RAM] = fakeBool;
}
}

static void _GBACoreReloadConfigOption(struct mCore* core, const char* option, const struct mCoreConfig* config) {
Expand Down Expand Up @@ -399,6 +406,19 @@ static void _GBACoreReloadConfigOption(struct mCore* core, const char* option, c
GBAVideoAssociateRenderer(&gba->video, renderer);
}
}

if (strcmp("gba.extensions", option) == 0) {
if (mCoreConfigGetIntValue(config, "gba.extensions", &fakeBool)) {
gba->extensions.userGlobalEnabled = fakeBool;
}
return;
}
if (strcmp("gba.ext.extraRam", option) == 0) {
if (mCoreConfigGetIntValue(config, "gba.ext.extraRam", &fakeBool)) {
gba->extensions.userExtensionsEnabled[GBAEX_ID_EXTRA_RAM] = fakeBool;
}
return;
}
}

static void _GBACoreDesiredVideoDimensions(const struct mCore* core, unsigned* width, unsigned* height) {
Expand Down Expand Up @@ -1152,6 +1172,25 @@ static void _GBACoreEndVideoLog(struct mCore* core) {
}
#endif

static size_t _GBAExtDataSerialize(struct mCore* core, enum mStateExtdataTag tag, void** sram) {
size_t size;
if (tag == EXTDATA_GBA_EXTENSIONS) {
return GBAExtensionsSerialize(core->board, sram);
} else {
size = 0;
*sram = NULL;
}

return size;
}

static bool _GBAExtDataDeserialize(struct mCore* core, enum mStateExtdataTag tag, const void* sram, size_t size) {
if (tag == EXTDATA_GBA_EXTENSIONS) {
return GBAExtensionsDeserialize(core->board, sram, size);
}
return false;
}

struct mCore* GBACoreCreate(void) {
struct GBACore* gbacore = malloc(sizeof(*gbacore));
struct mCore* core = &gbacore->d;
Expand Down Expand Up @@ -1236,6 +1275,8 @@ struct mCore* GBACoreCreate(void) {
core->startVideoLog = _GBACoreStartVideoLog;
core->endVideoLog = _GBACoreEndVideoLog;
#endif
core->extDataSerialize = _GBAExtDataSerialize;
core->extDataDeserialize = _GBAExtDataDeserialize;
return core;
}

Expand Down
Loading