all repos — mgba @ 96da9c7ef1cec4b347d67f7258587efd77d3a849

mGBA Game Boy Advance Emulator

Partially implement LDR/STR and friends
Jeffrey Pfau jeffrey@endrift.com
Sat, 06 Apr 2013 04:16:27 -0700
commit

96da9c7ef1cec4b347d67f7258587efd77d3a849

parent

92e74a78e1d603b61783c2f1542ae28181a32867

2 files changed, 116 insertions(+), 59 deletions(-)

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

@@ -15,6 +15,7 @@ static inline int _ARMModeHasSPSR(enum PrivilegeMode mode) {

return mode != MODE_SYSTEM && mode != MODE_USER; } +// Addressing mode 1 static inline void _barrelShift(struct ARMCore* cpu, uint32_t opcode) { // TODO }

@@ -153,6 +154,24 @@ cpu->cpsr.z = !(D); \

cpu->cpsr.c = cpu->shifterCarryOut; \ } +#define ADDR_MODE_2_ADDRESS (address) +#define ADDR_MODE_2_RN (cpu->gprs[rn]) +#define ADDR_MODE_2_RM (cpu->gprs[rm]) +#define ADDR_MODE_2_IMMEDIATE (opcode & 0x00000FFF) +#define ADDR_MODE_2_INDEX(U_OP, M) (cpu->gprs[rn] U_OP M) +#define ADDR_MODE_2_WRITEBACK(ADDR) (cpu->gprs[rn] = ADDR) +#define ADDR_MODE_2_LSL(I) (cpu->gprs[rm] << I) +#define ADDR_MODE_2_LSR(I) (I ? ((uint32_t) cpu->gprs[rm]) >> I : 0) +#define ADDR_MODE_2_ASR(I) (I ? ((int32_t) cpu->gprs[rm]) >> I : ((int32_t) cpu->gprs[rm]) >> 31) +#define ADDR_MODE_2_ROR(I) (I ? ARM_ROR(cpu->gprs[rm], I) : (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1)) + +#define ADDR_MODE_3_ADDRESS ADDR_MODE_2_ADDRESS +#define ADDR_MODE_3_RN ADDR_MODE_2_RN +#define ADDR_MODE_3_RM ADDR_MODE_2_RM +#define ADDR_MODE_3_IMMEDIATE ADDR_MODE_2_IMMEDIATE +#define ADDR_MODE_3_INDEX(U_OP, M) ADDR_MODE_2_INDEX(U_OP, M) +#define ADDR_MODE_3_WRITEBACK(ADDR) ADDR_MODE_2_WRITEBACK(ADDR) + #define DEFINE_INSTRUCTION_EX_ARM(NAME, COND, COND_BODY, BODY) \ static void _ARMInstruction ## NAME ## COND (struct ARMCore* cpu, uint32_t opcode) { \ if (!COND_BODY) { \

@@ -193,27 +212,44 @@ DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S, S_BODY, _barrelShift, BODY, POST_BODY) \

DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## I, , _immediate, BODY, POST_BODY) \ DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## SI, S_BODY, _immediate, BODY, POST_BODY) -#define DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDRESS, BODY) \ - DEFINE_INSTRUCTION_ARM(NAME ## ADDRESS, \ - BODY;) +#define DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDRESS, WRITEBACK, BODY) \ + DEFINE_INSTRUCTION_ARM(NAME, \ + uint32_t address; \ + int rn = (opcode >> 16) & 0xF; \ + int rd = (opcode >> 12) & 0xF; \ + int rm = opcode & 0xF; \ + address = ADDRESS; \ + BODY; \ + WRITEBACK;) +// TODO: shifters #define DEFINE_LOAD_STORE_INSTRUCTION_ARM(NAME, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, , BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, W, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, U, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, UW, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, P, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, PW, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, PU, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, PUW, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, I, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IW, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IU, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IUW, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IP, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IPW, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IPU, BODY) \ - DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, IPUW, BODY) + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, ADDR_MODE_2_RM)), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## U, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, ADDR_MODE_2_RM)), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## P, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_RM), , BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PW, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_RM), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PU, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_RM), , BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PUW, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_RM), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## I, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE)), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IU, ADDR_MODE_2_RN, ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE)), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IP, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE), , BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPW, ADDR_MODE_2_INDEX(-, ADDR_MODE_2_IMMEDIATE), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPU, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE), , BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPUW, ADDR_MODE_2_INDEX(+, ADDR_MODE_2_IMMEDIATE), ADDR_MODE_2_WRITEBACK(ADDR_MODE_2_ADDRESS), BODY) \ + +#define DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(NAME, BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDR_MODE_3_RN, ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM)), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## U, ADDR_MODE_3_RN, ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM)), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## P, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM), , BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PW, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_RM), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PU, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM), , BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## PUW, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_RM), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## I, ADDR_MODE_3_RN, ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE)), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IU, ADDR_MODE_3_RN, ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE)), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IP, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE), , BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPW, ADDR_MODE_3_INDEX(-, ADDR_MODE_3_IMMEDIATE), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPU, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE), , BODY) \ + DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME ## IPUW, ADDR_MODE_3_INDEX(+, ADDR_MODE_3_IMMEDIATE), ADDR_MODE_3_WRITEBACK(ADDR_MODE_3_ADDRESS), BODY) \ // Begin ALU definitions

@@ -289,14 +325,14 @@ // End multiply definitions

// Begin load/store definitions -DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDR,) -DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB,) -DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRH,) -DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRSB,) -DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRSH,) -DEFINE_LOAD_STORE_INSTRUCTION_ARM(STR,) -DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRB,) -DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRH,) +DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDR, cpu->gprs[rd] = cpu->memory->load32(cpu->memory, address)) +DEFINE_LOAD_STORE_INSTRUCTION_ARM(LDRB, cpu->gprs[rd] = cpu->memory->loadU8(cpu->memory, address)) +DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRH, cpu->gprs[rd] = cpu->memory->loadU16(cpu->memory, address)) +DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSB, cpu->gprs[rd] = cpu->memory->load8(cpu->memory, address)) +DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(LDRSH, cpu->gprs[rd] = cpu->memory->load16(cpu->memory, address)) +DEFINE_LOAD_STORE_INSTRUCTION_ARM(STR, cpu->memory->store32(cpu->memory, address, cpu->gprs[rd])) +DEFINE_LOAD_STORE_INSTRUCTION_ARM(STRB, cpu->memory->store8(cpu->memory, address, cpu->gprs[rd])) +DEFINE_LOAD_STORE_MODE_3_INSTRUCTION_ARM(STRH, cpu->memory->store16(cpu->memory, address, cpu->gprs[rd])) DEFINE_INSTRUCTION_ARM(SWP,) DEFINE_INSTRUCTION_ARM(SWPB,)

@@ -341,6 +377,23 @@

#define DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, NAME, P, U, W) \ DO_8(DECLARE_INSTRUCTION_ARM(COND, NAME ## I ## P ## U ## W)) \ DO_8(DECLARE_INSTRUCTION_ARM(COND, NAME ## I ## P ## U ## W)) + +#define LDRHW ILL +#define LDRSBW ILL +#define LDRSHW ILL +#define LDRHIW ILL +#define LDRSBIW ILL +#define LDRSHIW ILL +#define LDRHUW ILL +#define LDRSBUW ILL +#define LDRSHUW ILL +#define LDRHIUW ILL +#define LDRSBIUW ILL +#define LDRSHIUW ILL +#define STRHIW ILL +#define STRHIUW ILL +#define STRHUW ILL +#define STRHW ILL #define DECLARE_COND_BLOCK(COND) \ DECLARE_ARM_ALU_BLOCK(COND, AND, MUL, STRH, ILL, ILL), \

@@ -407,38 +460,38 @@ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(COND, BIC), \

DECLARE_ARM_ALU_IMMEDIATE_BLOCK(COND, BICS), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(COND, MVN), \ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(COND, MVNS)//, \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , , ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , , ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , , W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , , W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , , ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , , ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , , W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , , W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , U, ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , U, ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , U, W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , U, W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , U, ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , U, ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , U, W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , U, W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, , ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, , ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, , W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, , W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, , ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, , ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, , W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, , W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, U, ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, U, ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, U, W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, U, W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, U, ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, U, ), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, U, W), \ - // DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, U, W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , , ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , , ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , , W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , , W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , , ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , , ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , , W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , , W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , U, ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , U, ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, , U, W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, , U, W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , U, ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , U, ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, , U, W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, , U, W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, , ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, , ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, , W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, , W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, , ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, , ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, , W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, , W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, U, ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, U, ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STR, P, U, W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDR, P, U, W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, U, ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, U, ), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, STRB, P, U, W), \ + DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(COND, LDRB, P, U, W), \ // DECLARE_ARM_LOAD_STORE_BLOCK(COND, STR, , , ), \ // DECLARE_ARM_LOAD_STORE_BLOCK(COND, LDR, , , ), \ // DECLARE_ARM_LOAD_STORE_BLOCK(COND, STR, , , W), \
M src/arm.hsrc/arm.h

@@ -64,6 +64,10 @@ 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); + + void (*store32)(struct ARMMemory*, uint32_t address, int32_t value); + void (*store16)(struct ARMMemory*, uint32_t address, int16_t value); + void (*store8)(struct ARMMemory*, uint32_t address, int8_t value); }; struct ARMBoard {