all repos — mgba @ bf72532715909619ac341b754d8411ead4468244

mGBA Game Boy Advance Emulator

Add more framework for loading instructions
Jeffrey Pfau jeffrey@endrift.com
Wed, 03 Apr 2013 22:34:49 -0700
commit

bf72532715909619ac341b754d8411ead4468244

parent

009bef870c3539918be19d01bb1f2b0cd2e8f84f

2 files changed, 64 insertions(+), 1 deletions(-)

jump to
M src/arm.csrc/arm.c

@@ -1,5 +1,38 @@

#include "arm.h" +static void _ARMSetMode(struct ARMCore*, enum ExecutionMode); +static ARMInstruction _ARMLoadInstructionARM(struct ARMMemory*, uint32_t address); +static ARMInstruction _ARMLoadInstructionThumb(struct ARMMemory*, uint32_t address); + +static void _ARMSetMode(struct ARMCore* cpu, enum ExecutionMode executionMode) { + if (executionMode == cpu->executionMode) { + return; + } + + cpu->executionMode = executionMode; + switch (executionMode) { + case MODE_ARM: + cpu->cpsr.t = 0; + cpu->instructionWidth = WORD_SIZE_ARM; + cpu->loadInstruction = _ARMLoadInstructionARM; + break; + case MODE_THUMB: + cpu->cpsr.t = 1; + cpu->instructionWidth = WORD_SIZE_THUMB; + cpu->loadInstruction = _ARMLoadInstructionThumb; + } +} + +static ARMInstruction _ARMLoadInstructionARM(struct ARMMemory* memory, uint32_t address) { + int32_t opcode = memory->load32(memory, address); + return 0; +} + +static ARMInstruction _ARMLoadInstructionThumb(struct ARMMemory* memory, uint32_t address) { + uint16_t opcode = memory->loadU16(memory, address); + return 0; +} + void ARMInit(struct ARMCore* cpu) { int i; for (i = 0; i < 16; ++i) {

@@ -16,8 +49,16 @@ cpu->shifterCarryOut = 0;

cpu->memory = 0; cpu->board = 0; + + cpu->executionMode = MODE_THUMB; + _ARMSetMode(cpu, MODE_ARM); +} + +void ARMAssociateMemory(struct ARMCore* cpu, struct ARMMemory* memory) { + cpu->memory = memory; } void ARMCycle(struct ARMCore* cpu) { // TODO + ARMInstruction instruction = cpu->loadInstruction(cpu->memory, cpu->gprs[ARM_PC] - cpu->instructionWidth); }
M src/arm.hsrc/arm.h

@@ -24,6 +24,11 @@ MODE_UNDEFINED = 0x1B,

MODE_SYSTEM = 0x1F }; +enum WordSize { + WORD_SIZE_ARM = 4, + WORD_SIZE_THUMB = 2 +}; + enum ExecutionVector { BASE_RESET = 0x00000000, BASE_UNDEF = 0x00000004,

@@ -34,6 +39,9 @@ BASE_IRQ = 0x00000018,

BASE_FIQ = 0x0000001C }; +struct ARMCore; +typedef void (*ARMInstruction)(struct ARMCore*); + union PSR { struct { int exec : 4;

@@ -51,7 +59,14 @@

int32_t packed; }; -struct ARMMemory; +struct ARMMemory { + int32_t (*load32)(struct ARMMemory*, uint32_t address); + int16_t (*load16)(struct ARMMemory*, uint32_t address); + uint16_t (*loadU16)(struct ARMMemory*, uint32_t address); + int8_t (*load8)(struct ARMMemory*, uint32_t address); + uint8_t (*loadU8)(struct ARMMemory*, uint32_t address); +}; + struct ARMBoard; struct ARMCore {

@@ -64,11 +79,18 @@

int32_t shifterOperand; int32_t shifterCarryOut; + int instructionWidth; + + ARMInstruction (*loadInstruction)(struct ARMMemory*, uint32_t address); + enum ExecutionMode executionMode; + struct ARMMemory* memory; struct ARMBoard* board; }; void ARMInit(struct ARMCore* cpu); +void ARMAssociateMemory(struct ARMCore* cpu, struct ARMMemory* memory); + void ARMCycle(struct ARMCore* cpu); #endif