ARM: Partially fix LDM/STM writeback with empty register list

This commit is contained in:
Vicki Pfau 2019-11-01 19:37:08 -07:00
parent f336219a61
commit 89c49f15d0
4 changed files with 17 additions and 1 deletions

View File

@ -88,6 +88,7 @@ Misc:
Changes from beta 1: Changes from beta 1:
Emulation fixes: Emulation fixes:
- ARM: Fix STR writeback pipeline stage - ARM: Fix STR writeback pipeline stage
- ARM: Partially fix LDM/STM writeback with empty register list
- GBA DMA: Fix case where DMAs could get misaligned (fixes mgba.io/i/1092) - GBA DMA: Fix case where DMAs could get misaligned (fixes mgba.io/i/1092)
Other fixes: Other fixes:
- 3DS: Fix screen darkening (fixes mgba.io/i/1562) - 3DS: Fix screen darkening (fixes mgba.io/i/1562)

View File

@ -601,7 +601,7 @@ DEFINE_LOAD_STORE_T_INSTRUCTION_ARM(STRT, STORE,
DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM, DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM,
load, load,
currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32;
if (rs & 0x8000) { if ((rs & 0x8000) || !rs) {
currentCycles += ARMWritePC(cpu); currentCycles += ARMWritePC(cpu);
}) })

View File

@ -295,6 +295,9 @@ DEFINE_LOAD_STORE_MULTIPLE_THUMB(LDMIA,
IA, IA,
, ,
THUMB_LOAD_POST_BODY; THUMB_LOAD_POST_BODY;
if (!rs) {
currentCycles += ThumbWritePC(cpu);
}
if (!((1 << rn) & rs)) { if (!((1 << rn) & rs)) {
cpu->gprs[rn] = address; cpu->gprs[rn] = address;
}) })

View File

@ -1326,6 +1326,12 @@ void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old)
} }
#define LDM_LOOP(LDM) \ #define LDM_LOOP(LDM) \
if (UNLIKELY(!mask)) { \
LDM; \
cpu->gprs[ARM_PC] = value; \
wait += 16; \
address += 64; \
} \
for (i = 0; i < 16; i += 4) { \ for (i = 0; i < 16; i += 4) { \
if (UNLIKELY(mask & (1 << i))) { \ if (UNLIKELY(mask & (1 << i))) { \
LDM; \ LDM; \
@ -1438,6 +1444,12 @@ uint32_t GBALoadMultiple(struct ARMCore* cpu, uint32_t address, int mask, enum L
} }
#define STM_LOOP(STM) \ #define STM_LOOP(STM) \
if (UNLIKELY(!mask)) { \
value = cpu->gprs[ARM_PC] + (cpu->executionMode == MODE_ARM ? WORD_SIZE_ARM : WORD_SIZE_THUMB); \
STM; \
wait += 16; \
address += 64; \
} \
for (i = 0; i < 16; i += 4) { \ for (i = 0; i < 16; i += 4) { \
if (UNLIKELY(mask & (1 << i))) { \ if (UNLIKELY(mask & (1 << i))) { \
value = cpu->gprs[i]; \ value = cpu->gprs[i]; \