-
-
Notifications
You must be signed in to change notification settings - Fork 804
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
base: master
Are you sure you want to change the base?
GBA hardware extensions #2251
Changes from 20 commits
0051c82
cf6d9ef
9831a24
e563a36
7bba0eb
acc10c3
7a12e6a
36f5879
71e4e6c
58450e6
e3d7cad
6223cd7
3b0b9c3
77a0db9
cedf69f
b65493b
165e597
558a008
ece8c5a
97dac47
274183e
11a7413
d89678a
b2c2e55
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
/build | ||
/build-* | ||
/.vs | ||
/.vscode | ||
|
||
*.a | ||
*.dylib | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -160,6 +160,9 @@ struct mCore { | |
void (*startVideoLog)(struct mCore*, struct mVideoLogContext*); | ||
void (*endVideoLog)(struct mCore*); | ||
#endif | ||
|
||
size_t (*hwExtensionsSerialize)(struct mCore*, void** sram); | ||
bool (*hwExtensionsDeserialize)(struct mCore*, const void* sram, size_t size); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would probably make more sense to have a "generic" extdata serialize that you specify via passing in an extdata flag. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
}; | ||
|
||
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ enum mStateExtdataTag { | |
EXTDATA_SAVEDATA = 2, | ||
EXTDATA_CHEATS = 3, | ||
EXTDATA_RTC = 4, | ||
EXTDATA_HW_EXTENSIONS = 5, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Extensions should probably have a larger ID, I'm trying to reserve low IDs for things that are standard on systems. Maybe 0x80. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe 0x1F? To make it consistent with the SAVESTATE_HW_EXTENSIONS define. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. Changed the enum to 0x80 and left the define as it was. |
||
EXTDATA_META_TIME = 0x101, | ||
EXTDATA_MAX | ||
}; | ||
|
@@ -25,6 +26,7 @@ enum mStateExtdataTag { | |
#define SAVESTATE_CHEATS 4 | ||
#define SAVESTATE_RTC 8 | ||
#define SAVESTATE_METADATA 16 | ||
#define SAVESTATE_HW_EXTENSIONS 32 | ||
|
||
struct mStateExtdataItem { | ||
int32_t size; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,14 @@ CXX_GUARD_START | |
|
||
#include <mgba/debugger/debugger.h> | ||
|
||
#include <mgba/internal/gba/extra/extensions-ids.h> | ||
|
||
enum HwExSettingsOverrides { | ||
HWEX_DONT_OVERRIDE = 0, | ||
HWEX_ENABLE = 1, | ||
HWEX_DISABLE = 2, | ||
}; | ||
|
||
struct mArguments { | ||
char* fname; | ||
char* patch; | ||
|
@@ -29,6 +37,9 @@ struct mArguments { | |
bool debugAtStart; | ||
bool showHelp; | ||
bool showVersion; | ||
|
||
char hwExtensions; | ||
char hwExtensionsFlags[HWEX_EXTENSIONS_COUNT]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above about configuration. Passing in via a -C flag is probably a better idea, at least for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also removed this. |
||
}; | ||
|
||
struct mCoreConfig; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* Copyright (c) 2013-2021 Jeffrey Pfau | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file should still be merged into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
* | ||
* 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_IDS_H | ||
#define GBA_EXTENSIONS_IDS_H | ||
|
||
enum GBA_EXTENSIONS_IDS { | ||
HWEX_ID_MORE_RAM = 0, | ||
HWEX_EXTENSIONS_COUNT | ||
}; | ||
|
||
#define HWEX_FLAGS_REGISTERS_COUNT ((HWEX_EXTENSIONS_COUNT / 16) + (HWEX_EXTENSIONS_COUNT % 16 ? 1 : 0)) | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* 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/internal/gba/extra/extensions-ids.h> | ||
|
||
#define REG_HWEX_VERSION_VALUE HWEX_EXTENSIONS_COUNT | ||
#define HWEX_MORE_RAM_SIZE 0x100000 // 1 MB | ||
|
||
struct GBAExtensions { | ||
bool enabled; | ||
bool userEnabled; | ||
uint16_t userEnabledFlags[HWEX_FLAGS_REGISTERS_COUNT]; | ||
|
||
// IO: | ||
uint16_t io[REG_HWEX_END - REG_HWEX_ENABLE]; | ||
|
||
// Other data | ||
uint32_t moreRam[HWEX_MORE_RAM_SIZE / sizeof(uint32_t)]; | ||
}; | ||
|
||
struct GBAExtensionsState { | ||
uint32_t enabled; // boolean | ||
uint32_t version; | ||
|
||
// IO: | ||
uint32_t memory[128]; | ||
|
||
// Other data | ||
uint32_t moreRam[HWEX_MORE_RAM_SIZE / sizeof(uint32_t)]; | ||
}; | ||
|
||
struct GBA; | ||
void GBAExtensionsInit(struct GBAExtensions* hw); | ||
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); | ||
bool GBAExtensionsSerialize(struct GBA* gba, struct GBAExtensionsState* state); | ||
bool GBAExtensionsDeserialize(struct GBA* gba, const struct GBAExtensionsState* state, size_t size); | ||
|
||
CXX_GUARD_END | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -157,6 +157,31 @@ enum GBAIORegisters { | |
REG_DEBUG_STRING = 0xFFF600, | ||
REG_DEBUG_FLAGS = 0xFFF700, | ||
REG_DEBUG_ENABLE = 0xFFF780, | ||
|
||
// Extensions | ||
REG_HWEX_ENABLE = 0x400A00, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This base seems arbitrary. How did you choose it? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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, | ||
REG_HWEX_ENABLE_FLAGS_0 = 0x400A04, | ||
REG_HWEX_ENABLE_FLAGS_1 = 0x400A06, | ||
REG_HWEX_ENABLE_FLAGS_2 = 0x400A08, | ||
REG_HWEX_ENABLE_FLAGS_3 = 0x400A0A, | ||
REG_HWEX_ENABLE_FLAGS_4 = 0x400A0C, | ||
REG_HWEX_ENABLE_FLAGS_5 = 0x400A0E, | ||
|
||
// More RAM | ||
REG_HWEX0_CNT = 0x400A10, | ||
REG_HWEX0_RET_CODE = 0x400A12, | ||
REG_HWEX0_P0_LO = 0x400A14, // command | ||
REG_HWEX0_P0_HI = 0x400A16, | ||
REG_HWEX0_P1_LO = 0x400A18, // index | ||
REG_HWEX0_P1_HI = 0x400A1A, | ||
REG_HWEX0_P2_LO = 0x400A1C, // data pointer | ||
REG_HWEX0_P2_HI = 0x400A1E, | ||
REG_HWEX0_P3_LO = 0x400A20, // size | ||
REG_HWEX0_P3_HI = 0x400A22, | ||
|
||
REG_HWEX_END = 0x400A24, | ||
|
||
}; | ||
|
||
mLOG_DECLARE_CATEGORY(GBA_IO); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -440,6 +440,29 @@ void mCoreConfigMap(const struct mCoreConfig* config, struct mCoreOptions* opts) | |
_lookupCharValue(config, "screenshotPath", &opts->screenshotPath); | ||
_lookupCharValue(config, "patchPath", &opts->patchPath); | ||
_lookupCharValue(config, "cheatsPath", &opts->cheatsPath); | ||
|
||
_lookupIntValue(config, "hwExtensions", &fakeBool); | ||
opts->hwExtensions = fakeBool; | ||
|
||
const char hexDigits[] = "0123456789ABCDEF"; | ||
char hwExtensionsFlagsKey[] = "hwExtensionsFlags_XXXX"; | ||
for (size_t index = 0; index <= (HWEX_EXTENSIONS_COUNT >> 4); index++) { | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 3] = hexDigits[index & 0xF]; | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 4] = hexDigits[(index >> 4) & 0xF]; | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 5] = hexDigits[(index >> 8) & 0xF]; | ||
|
||
for (size_t offset = 0; offset < 0x10 && ((index << 4) + offset) < HWEX_EXTENSIONS_COUNT; offset++) { | ||
uint16_t bitFlag = (1 << offset); | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 2] = hexDigits[offset]; | ||
if (_lookupIntValue(config, hwExtensionsFlagsKey, &fakeBool)) { | ||
if (fakeBool) { | ||
opts->hwExtensionsFlags[index] |= bitFlag; | ||
} else { | ||
opts->hwExtensionsFlags[index] &= 0xFFFF ^ bitFlag; | ||
} | ||
} | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't belong in the core config. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also removed this. |
||
} | ||
|
||
void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct mCoreOptions* opts) { | ||
|
@@ -465,6 +488,21 @@ void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct mCoreOptio | |
ConfigurationSetIntValue(&config->defaultsTable, 0, "lockIntegerScaling", opts->lockIntegerScaling); | ||
ConfigurationSetIntValue(&config->defaultsTable, 0, "resampleVideo", opts->resampleVideo); | ||
ConfigurationSetIntValue(&config->defaultsTable, 0, "suspendScreensaver", opts->suspendScreensaver); | ||
|
||
ConfigurationSetIntValue(&config->defaultsTable, 0, "hwExtensions", opts->hwExtensions); | ||
|
||
const char hexDigits[] = "0123456789ABCDEF"; | ||
char hwExtensionsFlagsKey[] = "hwExtensionsFlags_XXXX"; | ||
for (size_t index = 0; index <= HWEX_EXTENSIONS_COUNT; index++) { | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 3] = hexDigits[index & 0xF]; | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 4] = hexDigits[(index >> 4) & 0xF]; | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 5] = hexDigits[(index >> 8) & 0xF]; | ||
|
||
for (size_t offset = 0; offset < 0x10 && ((index << 4) + offset) < HWEX_EXTENSIONS_COUNT; offset++) { | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 2] = hexDigits[offset]; | ||
ConfigurationSetIntValue(&config->defaultsTable, 0, hwExtensionsFlagsKey, (opts->hwExtensionsFlags[index] & (1 << offset)) != 0); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also removed this. |
||
} | ||
|
||
static void _configEnum(const char* key, const char* value, void* user) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,9 @@ | |
" -6 6x viewport\n" \ | ||
" -f Start full-screen" | ||
|
||
#define HWEX_ARGS_OFFSET 0x1002 | ||
#define HWEX_ARGS_NO_OFFSET (HWEX_ARGS_OFFSET + HWEX_EXTENSIONS_COUNT) | ||
|
||
static const struct option _options[] = { | ||
{ "bios", required_argument, 0, 'b' }, | ||
{ "cheats", required_argument, 0, 'c' }, | ||
|
@@ -42,6 +45,13 @@ static const struct option _options[] = { | |
{ "savestate", required_argument, 0, 't' }, | ||
{ "patch", required_argument, 0, 'p' }, | ||
{ "version", no_argument, 0, '\0' }, | ||
// Extensions | ||
{ "hw-extensions", no_argument, 0, HWEX_ARGS_OFFSET - 4 }, | ||
{ "no-hw-extensions", no_argument, 0, HWEX_ARGS_OFFSET - 3 }, | ||
{ "hwex-all", no_argument, 0, HWEX_ARGS_OFFSET - 2 }, | ||
{ "hwex-none", no_argument, 0, HWEX_ARGS_OFFSET - 1 }, | ||
{ "hwex-more-ram", no_argument, 0, HWEX_ARGS_OFFSET + HWEX_ID_MORE_RAM }, | ||
{ "no-hwex-more-ram", no_argument, 0, HWEX_ARGS_NO_OFFSET + HWEX_ID_MORE_RAM }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above about command line flags. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also removed this. |
||
{ 0, 0, 0, 0 } | ||
}; | ||
|
||
|
@@ -135,6 +145,32 @@ bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct | |
case 't': | ||
args->savestate = strdup(optarg); | ||
break; | ||
|
||
// Extensions | ||
case HWEX_ARGS_OFFSET - 4: | ||
// enable extensions | ||
args->hwExtensions = HWEX_ENABLE; | ||
break; | ||
case HWEX_ARGS_OFFSET - 3: | ||
// enable extensions | ||
args->hwExtensions = HWEX_DISABLE; | ||
break; | ||
case HWEX_ARGS_OFFSET - 2: | ||
// enable all extensions | ||
memset(args->hwExtensionsFlags, HWEX_ENABLE, sizeof(args->hwExtensionsFlags)); | ||
break; | ||
case HWEX_ARGS_OFFSET - 1: | ||
// disable all extensions | ||
memset(args->hwExtensionsFlags, HWEX_DISABLE, sizeof(args->hwExtensionsFlags)); | ||
break; | ||
case HWEX_ARGS_OFFSET + HWEX_ID_MORE_RAM: | ||
// enable 1 extension | ||
args->hwExtensionsFlags[ch - HWEX_ARGS_OFFSET] = HWEX_ENABLE; | ||
break; | ||
case HWEX_ARGS_NO_OFFSET + HWEX_ID_MORE_RAM: | ||
// disable 1 extension | ||
args->hwExtensionsFlags[ch - HWEX_ARGS_OFFSET] = HWEX_ENABLE; | ||
break; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also removed this. |
||
default: | ||
if (subparser) { | ||
if (!subparser->parse(subparser, ch, optarg)) { | ||
|
@@ -166,6 +202,20 @@ void applyArguments(const struct mArguments* args, struct mSubParser* subparser, | |
if (args->bios) { | ||
mCoreConfigSetOverrideValue(config, "bios", args->bios); | ||
} | ||
if (args->hwExtensions) { | ||
mCoreConfigSetOverrideIntValue(config, "hwExtensions", args->hwExtensions == HWEX_ENABLE); | ||
} | ||
const char hexDigits[] = "0123456789ABCDEF"; | ||
char hwExtensionsFlagsKey[] = "hwExtensionsFlags_XXXX"; | ||
for (size_t i = 0; i < (sizeof(args->hwExtensionsFlags) / sizeof(args->hwExtensionsFlags[0])); i++) { | ||
if (args->hwExtensionsFlags[i]) { | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 2] = hexDigits[i & 0xF]; | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 3] = hexDigits[(i >> 4) & 0xF]; | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 4] = hexDigits[(i >> 8) & 0xF]; | ||
hwExtensionsFlagsKey[sizeof(hwExtensionsFlagsKey) - 5] = hexDigits[(i >> 12) & 0xF]; | ||
mCoreConfigSetOverrideIntValue(config, hwExtensionsFlagsKey, args->hwExtensionsFlags[i] == HWEX_ENABLE); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also removed this. |
||
HashTableEnumerate(&args->configOverrides, _tableApply, config); | ||
if (subparser) { | ||
subparser->apply(subparser, config); | ||
|
@@ -248,6 +298,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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also removed this. |
||
if (extraOptions) { | ||
puts(extraOptions); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ set(SOURCE_FILES | |
cheats/parv3.c | ||
core.c | ||
dma.c | ||
extra/extensions.c | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Extras go in the There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should not be in the core opts since they're specific to one core.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed them.