diff --git a/src/arm.c b/src/arm.c index b1d5254ed..cdd6b5601 100644 --- a/src/arm.c +++ b/src/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 @@ void ARMInit(struct ARMCore* cpu) { 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); } \ No newline at end of file diff --git a/src/arm.h b/src/arm.h index f26f4ce74..0873bd930 100644 --- a/src/arm.h +++ b/src/arm.h @@ -24,6 +24,11 @@ enum PrivilegeMode { 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 @@ enum ExecutionVector { BASE_FIQ = 0x0000001C }; +struct ARMCore; +typedef void (*ARMInstruction)(struct ARMCore*); + union PSR { struct { int exec : 4; @@ -51,7 +59,14 @@ union PSR { 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 @@ struct ARMCore { 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 \ No newline at end of file