Invalid memory reads

This commit is contained in:
Jeffrey Pfau 2013-09-27 23:48:56 -07:00
parent 453fdac3fe
commit 25885e1e82
5 changed files with 28 additions and 6 deletions

View File

@ -111,6 +111,7 @@ struct ARMCore {
int32_t shifterOperand;
int32_t shifterCarryOut;
uint32_t currentPC;
enum ExecutionMode executionMode;
enum PrivilegeMode privilegeMode;

View File

@ -194,7 +194,8 @@ static ARMInstruction _ARMLoadInstructionARM(struct ARMMemory* memory, uint32_t
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;

View File

@ -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);
}

View File

@ -67,6 +67,7 @@ void GBAMemoryInit(struct GBAMemory* memory) {
memory->d.setActiveRegion = GBASetActiveRegion;
memory->d.activePrefetchCycles32 = 0;
memory->d.activePrefetchCycles16 = 0;
memory->biosPrefetch = 0;
memory->d.waitMultiple = GBAWaitMultiple;
}
@ -79,6 +80,9 @@ void GBAMemoryDeinit(struct GBAMemory* memory) {
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 @@ int32_t GBALoad32(struct ARMMemory* memory, uint32_t address, int* cycleCounter)
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 @@ int32_t GBALoad32(struct ARMMemory* memory, uint32_t address, int* cycleCounter)
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 @@ int16_t GBALoad16(struct ARMMemory* memory, uint32_t address, int* cycleCounter)
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 @@ int8_t GBALoad8(struct ARMMemory* memory, uint32_t address, int* cycleCounter) {
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;
}

View File

@ -122,6 +122,7 @@ struct GBAMemory {
char waitstatesPrefetch32[256];
char waitstatesPrefetch16[256];
int activeRegion;
uint32_t biosPrefetch;
struct GBADMA dma[4];
};