all repos — mgba @ 28ac288d2cc753aab0493a471726cc5795a09363

mGBA Game Boy Advance Emulator

ARM7: Extend prefetch by one stage
Jeffrey Pfau jeffrey@endrift.com
Sat, 20 Dec 2014 05:19:16 -0800
commit

28ac288d2cc753aab0493a471726cc5795a09363

parent

f57b47b3f24063d409d0a50f5fedacdd80ccc1f7

M CHANGESCHANGES

@@ -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
M src/arm/arm.csrc/arm/arm.c

@@ -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); }
M src/arm/arm.hsrc/arm/arm.h

@@ -149,7 +149,7 @@

int32_t shifterOperand; int32_t shifterCarryOut; - uint32_t prefetch; + uint32_t prefetch[2]; enum ExecutionMode executionMode; enum PrivilegeMode privilegeMode;
M src/arm/isa-inlines.hsrc/arm/isa-inlines.h

@@ -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) {
M src/gba/gba-memory.csrc/gba/gba-memory.c

@@ -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; }
M src/gba/gba-serialize.csrc/gba/gba-serialize.c

@@ -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);
M src/gba/gba.csrc/gba/gba.c

@@ -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) {