mirror of https://github.com/mgba-emu/mgba.git
GBA: Regrettably add VBA bug compat mode
This commit is contained in:
parent
60b59ae312
commit
20f8baa82c
1
CHANGES
1
CHANGES
|
@ -7,6 +7,7 @@ Features:
|
||||||
- Frame viewer support for Game Boy
|
- Frame viewer support for Game Boy
|
||||||
- Mute option in homebrew ports
|
- Mute option in homebrew ports
|
||||||
- Status indicators for fast-forward and mute in homebrew ports
|
- Status indicators for fast-forward and mute in homebrew ports
|
||||||
|
- VBA bug compatibility mode for ROM hacks that don't work on real hardware
|
||||||
- Read-only support for MBC6 flash memory
|
- Read-only support for MBC6 flash memory
|
||||||
- New unlicensed GB mappers: Pokémon Jade/Diamond, BBD, and Hitek
|
- New unlicensed GB mappers: Pokémon Jade/Diamond, BBD, and Hitek
|
||||||
- Stack tracing tools in ARM debugger (by ahigerd)
|
- Stack tracing tools in ARM debugger (by ahigerd)
|
||||||
|
|
|
@ -116,6 +116,7 @@ struct GBA {
|
||||||
int32_t cachedRegisters[16];
|
int32_t cachedRegisters[16];
|
||||||
bool taintedRegisters[16];
|
bool taintedRegisters[16];
|
||||||
|
|
||||||
|
bool vbaBugCompat;
|
||||||
bool hardCrash;
|
bool hardCrash;
|
||||||
bool allowOpposingDirections;
|
bool allowOpposingDirections;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ struct GBACartridgeOverride {
|
||||||
int hardware;
|
int hardware;
|
||||||
uint32_t idleLoop;
|
uint32_t idleLoop;
|
||||||
bool mirroring;
|
bool mirroring;
|
||||||
|
bool vbaBugCompat;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Configuration;
|
struct Configuration;
|
||||||
|
|
|
@ -108,6 +108,7 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) {
|
||||||
gba->idleOptimization = IDLE_LOOP_REMOVE;
|
gba->idleOptimization = IDLE_LOOP_REMOVE;
|
||||||
gba->idleLoop = IDLE_LOOP_NONE;
|
gba->idleLoop = IDLE_LOOP_NONE;
|
||||||
|
|
||||||
|
gba->vbaBugCompat = false;
|
||||||
gba->hardCrash = true;
|
gba->hardCrash = true;
|
||||||
gba->allowOpposingDirections = true;
|
gba->allowOpposingDirections = true;
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,12 @@ void GBAHardwareGPIOWrite(struct GBACartridgeHardware* hw, uint32_t address, uin
|
||||||
}
|
}
|
||||||
switch (address) {
|
switch (address) {
|
||||||
case GPIO_REG_DATA:
|
case GPIO_REG_DATA:
|
||||||
|
if (!hw->p->vbaBugCompat) {
|
||||||
hw->pinState &= ~hw->direction;
|
hw->pinState &= ~hw->direction;
|
||||||
hw->pinState |= value & hw->direction;
|
hw->pinState |= value & hw->direction;
|
||||||
|
} else {
|
||||||
|
hw->pinState = value;
|
||||||
|
}
|
||||||
_readPins(hw);
|
_readPins(hw);
|
||||||
break;
|
break;
|
||||||
case GPIO_REG_DIRECTION:
|
case GPIO_REG_DIRECTION:
|
||||||
|
|
|
@ -207,6 +207,7 @@ bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOver
|
||||||
override->hardware = HW_NONE;
|
override->hardware = HW_NONE;
|
||||||
override->idleLoop = IDLE_LOOP_NONE;
|
override->idleLoop = IDLE_LOOP_NONE;
|
||||||
override->mirroring = false;
|
override->mirroring = false;
|
||||||
|
override->vbaBugCompat = false;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
@ -320,6 +321,8 @@ void GBAOverrideApply(struct GBA* gba, const struct GBACartridgeOverride* overri
|
||||||
GBASavedataForceType(&gba->memory.savedata, override->savetype);
|
GBASavedataForceType(&gba->memory.savedata, override->savetype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gba->vbaBugCompat = override->vbaBugCompat;
|
||||||
|
|
||||||
if (override->hardware != HW_NO_OVERRIDE) {
|
if (override->hardware != HW_NO_OVERRIDE) {
|
||||||
GBAHardwareClear(&gba->memory.hw);
|
GBAHardwareClear(&gba->memory.hw);
|
||||||
|
|
||||||
|
@ -376,6 +379,7 @@ void GBAOverrideApplyDefaults(struct GBA* gba, const struct Configuration* overr
|
||||||
// Enable FLASH1M and RTC on Pokémon FireRed ROM hacks
|
// Enable FLASH1M and RTC on Pokémon FireRed ROM hacks
|
||||||
override.savetype = SAVEDATA_FLASH1M;
|
override.savetype = SAVEDATA_FLASH1M;
|
||||||
override.hardware = HW_RTC;
|
override.hardware = HW_RTC;
|
||||||
|
override.vbaBugCompat = true;
|
||||||
GBAOverrideApply(gba, &override);
|
GBAOverrideApply(gba, &override);
|
||||||
} else if (GBAOverrideFind(overrides, &override)) {
|
} else if (GBAOverrideFind(overrides, &override)) {
|
||||||
GBAOverrideApply(gba, &override);
|
GBAOverrideApply(gba, &override);
|
||||||
|
|
|
@ -142,6 +142,7 @@ void OverrideView::updateOverrides() {
|
||||||
gba->override.hardware = HW_NO_OVERRIDE;
|
gba->override.hardware = HW_NO_OVERRIDE;
|
||||||
gba->override.idleLoop = IDLE_LOOP_NONE;
|
gba->override.idleLoop = IDLE_LOOP_NONE;
|
||||||
gba->override.mirroring = false;
|
gba->override.mirroring = false;
|
||||||
|
gba->override.vbaBugCompat = false;
|
||||||
|
|
||||||
if (!m_ui.hwAutodetect->isChecked()) {
|
if (!m_ui.hwAutodetect->isChecked()) {
|
||||||
gba->override.hardware = HW_NONE;
|
gba->override.hardware = HW_NONE;
|
||||||
|
@ -164,6 +165,9 @@ void OverrideView::updateOverrides() {
|
||||||
if (m_ui.hwGBPlayer->isChecked()) {
|
if (m_ui.hwGBPlayer->isChecked()) {
|
||||||
gba->override.hardware |= HW_GB_PLAYER_DETECTION;
|
gba->override.hardware |= HW_GB_PLAYER_DETECTION;
|
||||||
}
|
}
|
||||||
|
if (m_ui.vbaBugCompat->isChecked()) {
|
||||||
|
gba->override.vbaBugCompat = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
uint32_t parsedIdleLoop = m_ui.idleLoop->text().toInt(&ok, 16);
|
uint32_t parsedIdleLoop = m_ui.idleLoop->text().toInt(&ok, 16);
|
||||||
|
@ -219,6 +223,7 @@ void OverrideView::gameStarted() {
|
||||||
m_ui.hwTilt->setChecked(gba->memory.hw.devices & HW_TILT);
|
m_ui.hwTilt->setChecked(gba->memory.hw.devices & HW_TILT);
|
||||||
m_ui.hwRumble->setChecked(gba->memory.hw.devices & HW_RUMBLE);
|
m_ui.hwRumble->setChecked(gba->memory.hw.devices & HW_RUMBLE);
|
||||||
m_ui.hwGBPlayer->setChecked(gba->memory.hw.devices & HW_GB_PLAYER_DETECTION);
|
m_ui.hwGBPlayer->setChecked(gba->memory.hw.devices & HW_GB_PLAYER_DETECTION);
|
||||||
|
m_ui.vbaBugCompat->setChecked(gba->vbaBugCompat);
|
||||||
|
|
||||||
if (gba->idleLoop != IDLE_LOOP_NONE) {
|
if (gba->idleLoop != IDLE_LOOP_NONE) {
|
||||||
m_ui.idleLoop->setText(QString::number(gba->idleLoop, 16));
|
m_ui.idleLoop->setText(QString::number(gba->idleLoop, 16));
|
||||||
|
|
|
@ -174,21 +174,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="hwGBPlayer">
|
<widget class="QCheckBox" name="hwGBPlayer">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -197,19 +182,11 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_3">
|
<widget class="QCheckBox" name="vbaBugCompat">
|
||||||
<property name="orientation">
|
<property name="text">
|
||||||
<enum>Qt::Horizontal</enum>
|
<string>VBA bug compatibility mode</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
</widget>
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
Loading…
Reference in New Issue