ARM7: Extend prefetch by one stage
@@ -10,6 +10,7 @@ - GBA Thread: Allow halted games to exit cleanly
- GBA BIOS: Fix HLE Lz77 and RL functions to properly account for width and invalid addresses - ARM7: Fix LDM writeback to a register already written - GBA Memory: Don't call into GPIO write calls if GPIO devices are absent + - ARM7: Extend prefetch by one stage Misc: - Qt: Disable sync to video by default - GBA: Exit cleanly on FATAL if the port supports it
@@ -176,9 +176,10 @@ cpu->cpsr.i = 1;
} static inline void ARMStep(struct ARMCore* cpu) { - uint32_t opcode = cpu->prefetch; - LOAD_32(cpu->prefetch, cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + uint32_t opcode = cpu->prefetch[0]; + cpu->prefetch[0] = cpu->prefetch[1]; cpu->gprs[ARM_PC] += WORD_SIZE_ARM; + LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); unsigned condition = opcode >> 28; if (condition != 0xE) {@@ -239,9 +240,10 @@ instruction(cpu, opcode);
} static inline void ThumbStep(struct ARMCore* cpu) { - uint32_t opcode = cpu->prefetch; - LOAD_16(cpu->prefetch, cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + uint32_t opcode = cpu->prefetch[0]; + cpu->prefetch[0] = cpu->prefetch[1]; cpu->gprs[ARM_PC] += WORD_SIZE_THUMB; + LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); ThumbInstruction instruction = _thumbTable[opcode >> 6]; instruction(cpu, opcode); }
@@ -149,7 +149,7 @@
int32_t shifterOperand; int32_t shifterCarryOut; - uint32_t prefetch; + uint32_t prefetch[2]; enum ExecutionMode executionMode; enum PrivilegeMode privilegeMode;
@@ -52,15 +52,17 @@
#define ARM_WRITE_PC \ cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM); \ cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); \ - LOAD_32(cpu->prefetch, cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ + LOAD_32(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ cpu->gprs[ARM_PC] += WORD_SIZE_ARM; \ + LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ currentCycles += 2 + cpu->memory.activeUncachedCycles32 + cpu->memory.activeSeqCycles32; #define THUMB_WRITE_PC \ cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB); \ cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); \ - LOAD_16(cpu->prefetch, cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ + LOAD_16(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ cpu->gprs[ARM_PC] += WORD_SIZE_THUMB; \ + LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ currentCycles += 2 + cpu->memory.activeUncachedCycles16 + cpu->memory.activeSeqCycles16; static inline int _ARMModeHasSPSR(enum PrivilegeMode mode) {
@@ -14,7 +14,7 @@ #include "hle-bios.h"
#include "util/memory.h" static uint32_t _popcount32(unsigned bits); -static uint32_t _deadbeef = 0xDEADBEEF; +static uint32_t _deadbeef[2] = { 0xDEADBEEF, 0xFEEDFACE }; static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t region); static void GBAMemoryServiceDMA(struct GBA* gba, int number, struct GBADMA* info);@@ -128,7 +128,7 @@ if (newRegion == memory->activeRegion) {
return; } if (memory->activeRegion == REGION_BIOS) { - memory->biosPrefetch = cpu->prefetch; + memory->biosPrefetch = cpu->prefetch[0]; } memory->activeRegion = newRegion; switch (address & ~OFFSET_MASK) {@@ -158,7 +158,7 @@ cpu->memory.activeRegion = memory->rom;
cpu->memory.activeMask = SIZE_CART0 - 1; break; default: - cpu->memory.activeRegion = &_deadbeef; + cpu->memory.activeRegion = _deadbeef; cpu->memory.activeMask = 0; GBALog(gba, GBA_LOG_FATAL, "Jumped to invalid address"); break;@@ -176,7 +176,7 @@ GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load32: 0x%08X", address); \
if (cpu->cycles >= cpu->nextEvent) { \ value = gba->bus; \ } else { \ - value = cpu->prefetch; \ + value = cpu->prefetch[0]; \ if (cpu->executionMode == MODE_THUMB) { \ value |= value << 16; \ } \@@ -303,7 +303,7 @@ GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address);
if (cpu->cycles >= cpu->nextEvent) { value = gba->bus; } else { - value = cpu->prefetch; + value = cpu->prefetch[0]; } } break;@@ -359,7 +359,7 @@ GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address);
if (cpu->cycles >= cpu->nextEvent) { value = gba->bus; } else { - value = cpu->prefetch; + value = cpu->prefetch[0]; } break; }@@ -396,7 +396,7 @@ GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address);
if (cpu->cycles >= cpu->nextEvent) { value = gba->bus; } else { - value = cpu->prefetch; + value = cpu->prefetch[0]; } } break;@@ -454,7 +454,7 @@ GBALog(gba, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address);
if (cpu->cycles >= cpu->nextEvent) { value = gba->bus; } else { - value = cpu->prefetch; + value = cpu->prefetch[0]; } break; }
@@ -82,10 +82,12 @@ gba->cpu->privilegeMode = gba->cpu->cpsr.priv;
gba->cpu->memory.setActiveRegion(gba->cpu, gba->cpu->gprs[ARM_PC]); if (gba->cpu->cpsr.t) { gba->cpu->executionMode = MODE_THUMB; - LOAD_16(gba->cpu->prefetch, (gba->cpu->gprs[ARM_PC] - WORD_SIZE_THUMB) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); + LOAD_16(gba->cpu->prefetch[0], (gba->cpu->gprs[ARM_PC] - WORD_SIZE_THUMB) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); + LOAD_16(gba->cpu->prefetch[1], (gba->cpu->gprs[ARM_PC]) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); } else { gba->cpu->executionMode = MODE_ARM; - LOAD_32(gba->cpu->prefetch, (gba->cpu->gprs[ARM_PC] - WORD_SIZE_ARM) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); + LOAD_32(gba->cpu->prefetch[0], (gba->cpu->gprs[ARM_PC] - WORD_SIZE_ARM) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); + LOAD_32(gba->cpu->prefetch[1], (gba->cpu->gprs[ARM_PC]) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); } GBAMemoryDeserialize(&gba->memory, state);
@@ -227,9 +227,9 @@ int32_t cycles = cpu->cycles;
int32_t nextEvent = INT_MAX; int32_t testEvent; - gba->bus = cpu->prefetch; + gba->bus = cpu->prefetch[0]; if (cpu->executionMode == MODE_THUMB) { - gba->bus |= cpu->prefetch << 16; + gba->bus |= cpu->prefetch[0] << 16; } if (gba->springIRQ) {