all repos — mgba @ 25885e1e82b3cef2e2efc4abafa8e615e714e5fd

mGBA Game Boy Advance Emulator

Invalid memory reads
Jeffrey Pfau jeffrey@endrift.com
Fri, 27 Sep 2013 23:48:56 -0700
commit

25885e1e82b3cef2e2efc4abafa8e615e714e5fd

parent

453fdac3fe7f33fdb978cadd519983d85f6ceaca

5 files changed, 28 insertions(+), 6 deletions(-)

jump to
M src/arm/arm.hsrc/arm/arm.h

@@ -111,6 +111,7 @@

int32_t shifterOperand; int32_t shifterCarryOut; + uint32_t currentPC; enum ExecutionMode executionMode; enum PrivilegeMode privilegeMode;
M src/arm/isa-arm.csrc/arm/isa-arm.c

@@ -194,7 +194,8 @@

void ARMStep(struct ARMCore* cpu) { // TODO uint32_t opcode; - ARMInstruction instruction = _ARMLoadInstructionARM(cpu->memory, cpu->gprs[ARM_PC] - WORD_SIZE_ARM, &opcode); + cpu->currentPC = cpu->gprs[ARM_PC] - WORD_SIZE_ARM; + ARMInstruction instruction = _ARMLoadInstructionARM(cpu->memory, cpu->currentPC, &opcode); cpu->gprs[ARM_PC] += WORD_SIZE_ARM; int condition = opcode >> 28;
M src/arm/isa-thumb.csrc/arm/isa-thumb.c

@@ -5,10 +5,9 @@

static const ThumbInstruction _thumbTable[0x400]; void ThumbStep(struct ARMCore* cpu) { - uint32_t address = cpu->gprs[ARM_PC]; - cpu->gprs[ARM_PC] = address + WORD_SIZE_THUMB; - address -= WORD_SIZE_THUMB; - uint16_t opcode = ((uint16_t*) cpu->memory->activeRegion)[(address & cpu->memory->activeMask) >> 1]; + cpu->currentPC = cpu->gprs[ARM_PC] - WORD_SIZE_THUMB; + cpu->gprs[ARM_PC] += WORD_SIZE_THUMB; + uint16_t opcode = ((uint16_t*) cpu->memory->activeRegion)[(cpu->currentPC & cpu->memory->activeMask) >> 1]; ThumbInstruction instruction = _thumbTable[opcode >> 6]; instruction(cpu, opcode); }
M src/gba/gba-memory.csrc/gba/gba-memory.c

@@ -67,6 +67,7 @@ memory->d.activeMask = 0;

memory->d.setActiveRegion = GBASetActiveRegion; memory->d.activePrefetchCycles32 = 0; memory->d.activePrefetchCycles16 = 0; + memory->biosPrefetch = 0; memory->d.waitMultiple = GBAWaitMultiple; }

@@ -79,6 +80,9 @@

static void GBASetActiveRegion(struct ARMMemory* memory, uint32_t address) { struct GBAMemory* gbaMemory = (struct GBAMemory*) memory; + if (gbaMemory->activeRegion == REGION_BIOS) { + gbaMemory->biosPrefetch = memory->load32(memory, gbaMemory->p->cpu.currentPC + WORD_SIZE_ARM * 2, 0); + } gbaMemory->activeRegion = address >> BASE_OFFSET; memory->activePrefetchCycles32 = gbaMemory->waitstatesPrefetch32[gbaMemory->activeRegion]; memory->activePrefetchCycles16 = gbaMemory->waitstatesPrefetch16[gbaMemory->activeRegion];

@@ -121,7 +125,15 @@ int wait = 0;

switch (address & ~OFFSET_MASK) { case BASE_BIOS: - GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Load32: 0x%08X", address); + if (gbaMemory->p->cpu.currentPC >> BASE_OFFSET == REGION_BIOS) { + if (address < hleBiosLength) { + value = gbaMemory->bios[address >> 2]; + } else { + value = 0; + } + } else { + value = gbaMemory->biosPrefetch; + } break; case BASE_WORKING_RAM: value = gbaMemory->wram[(address & (SIZE_WORKING_RAM - 1)) >> 2];

@@ -158,6 +170,12 @@ GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Load32: 0x%08X", address);

break; default: GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Bad memory Load32: 0x%08X", address); + if (gbaMemory->p->cpu.executionMode == MODE_ARM) { + value = memory->load32(memory, gbaMemory->p->cpu.currentPC + WORD_SIZE_ARM * 2, 0); + } else { + value = memory->load16(memory, gbaMemory->p->cpu.currentPC + WORD_SIZE_THUMB * 2, 0); + value |= value << 16; + } break; }

@@ -225,6 +243,7 @@ GBALog(gbaMemory->p, GBA_LOG_STUB, "Unimplemented memory Load16: 0x%08X", address);

break; default: GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Bad memory Load16: 0x%08X", address); + value = memory->load16(memory, gbaMemory->p->cpu.currentPC + (gbaMemory->p->cpu.executionMode == MODE_ARM ? WORD_SIZE_ARM : WORD_SIZE_THUMB) * 2, 0); break; }

@@ -292,6 +311,7 @@ }

break; default: GBALog(gbaMemory->p, GBA_LOG_GAME_ERROR, "Bad memory Load8: 0x%08x", address); + value = memory->load16(memory, gbaMemory->p->cpu.currentPC + (gbaMemory->p->cpu.executionMode == MODE_ARM ? WORD_SIZE_ARM : WORD_SIZE_THUMB) * 2, 0) >> ((address & 1) << 3); break; }
M src/gba/gba-memory.hsrc/gba/gba-memory.h

@@ -122,6 +122,7 @@ char waitstatesSeq16[256];

char waitstatesPrefetch32[256]; char waitstatesPrefetch16[256]; int activeRegion; + uint32_t biosPrefetch; struct GBADMA dma[4]; };