mirror of https://github.com/mgba-emu/mgba.git
Implement BX
This commit is contained in:
parent
a511df7920
commit
d278429b43
|
@ -1,6 +1,8 @@
|
|||
#include "arm.h"
|
||||
|
||||
#include "isa-arm.h"
|
||||
#include "isa-inlines.h"
|
||||
#include "isa-thumb.h"
|
||||
|
||||
static inline enum RegisterBank _ARMSelectBank(enum PrivilegeMode);
|
||||
|
||||
|
@ -107,7 +109,7 @@ void ARMReset(struct ARMCore* cpu) {
|
|||
}
|
||||
|
||||
void ARMRun(struct ARMCore* cpu) {
|
||||
if (cpu->executionMode) {
|
||||
if (cpu->executionMode == MODE_THUMB) {
|
||||
ThumbStep(cpu);
|
||||
} else {
|
||||
ARMStep(cpu);
|
||||
|
|
|
@ -126,10 +126,6 @@ void ARMStep(struct ARMCore* cpu) {
|
|||
// Instruction definitions
|
||||
// Beware pre-processor antics
|
||||
|
||||
#define ARM_WRITE_PC \
|
||||
cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM) + WORD_SIZE_ARM; \
|
||||
cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC]);
|
||||
|
||||
#define ARM_ADDITION_S(M, N, D) \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
||||
cpu->cpsr = cpu->spsr; \
|
||||
|
@ -412,7 +408,15 @@ DEFINE_INSTRUCTION_ARM(B, \
|
|||
ARM_WRITE_PC;)
|
||||
|
||||
DEFINE_INSTRUCTION_ARM(BL, ARM_STUB)
|
||||
DEFINE_INSTRUCTION_ARM(BX, ARM_STUB)
|
||||
DEFINE_INSTRUCTION_ARM(BX, \
|
||||
int rm = opcode & 0x0000000F; \
|
||||
_ARMSetMode(cpu, cpu->gprs[rm] & 0x00000001); \
|
||||
cpu->gprs[ARM_PC] = cpu->gprs[rm] & 0xFFFFFFFE; \
|
||||
if (cpu->executionMode == MODE_THUMB) { \
|
||||
THUMB_WRITE_PC;
|
||||
} else { \
|
||||
ARM_WRITE_PC; \
|
||||
})
|
||||
|
||||
// End branch definitions
|
||||
|
||||
|
|
|
@ -54,6 +54,14 @@
|
|||
|
||||
#define ARM_STUB cpu->board->hitStub(cpu->board, opcode)
|
||||
|
||||
#define ARM_WRITE_PC \
|
||||
cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM) + WORD_SIZE_ARM; \
|
||||
cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC]);
|
||||
|
||||
#define THUMB_WRITE_PC \
|
||||
cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB) + WORD_SIZE_THUMB; \
|
||||
cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC]);
|
||||
|
||||
static inline int _ARMModeHasSPSR(enum PrivilegeMode mode) {
|
||||
return mode != MODE_SYSTEM && mode != MODE_USER;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue