all repos — mgba @ d2e84f0a3034548cd9326e15127b045b135c7098

mGBA Game Boy Advance Emulator

Implement IntrWait
Jeffrey Pfau jeffrey@endrift.com
Fri, 26 Apr 2013 02:00:59 -0700
commit

d2e84f0a3034548cd9326e15127b045b135c7098

parent

7c895f6091fe282f53d2f54d3e90ed5588955e2a

3 files changed, 34 insertions(+), 0 deletions(-)

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

@@ -135,6 +135,24 @@ cpu->spsr = cpsr;

cpu->cpsr.i = 1; } +void ARMRaiseSWI(struct ARMCore* cpu) { + union PSR cpsr = cpu->cpsr; + int instructionWidth; + if (cpu->executionMode == MODE_THUMB) { + instructionWidth = WORD_SIZE_THUMB; + } else { + instructionWidth = WORD_SIZE_ARM; + } + ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR); + cpu->cpsr.priv = MODE_IRQ; + cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM; + cpu->gprs[ARM_PC] = BASE_SWI + WORD_SIZE_ARM; + cpu->memory->setActiveRegion(cpu->memory, cpu->gprs[ARM_PC]); + _ARMSetMode(cpu, MODE_ARM); + cpu->spsr = cpsr; + cpu->cpsr.i = 1; +} + void ARMRun(struct ARMCore* cpu) { if (cpu->executionMode == MODE_THUMB) { ThumbStep(cpu);
M src/arm/arm.hsrc/arm/arm.h

@@ -122,6 +122,7 @@

void ARMReset(struct ARMCore* cpu); void ARMSetPrivilegeMode(struct ARMCore*, enum PrivilegeMode); void ARMRaiseIRQ(struct ARMCore*); +void ARMRaiseSWI(struct ARMCore*); void ARMRun(struct ARMCore* cpu);
M src/gba/gba-bios.csrc/gba/gba-bios.c

@@ -1,6 +1,7 @@

#include "gba-bios.h" #include "gba.h" +#include "gba-io.h" #include "gba-memory.h" #include <math.h>

@@ -80,6 +81,20 @@ struct GBA* gba = ((struct GBABoard*) board)->p;

switch (immediate) { case 0x2: GBAHalt(gba); + break; + case 0x05: + // VBlankIntrWait + gba->cpu.gprs[0] = 1; + gba->cpu.gprs[1] = 1; + // Fall through: + case 0x04: + // IntrWait + gba->memory.io[REG_IME >> 1] = 1; + if (!gba->cpu.gprs[0] && gba->memory.io[REG_IF >> 1] & gba->cpu.gprs[1]) { + break; + } + gba->memory.io[REG_IF >> 1] = 0; + ARMRaiseSWI(&gba->cpu); break; case 0xB: _CpuSet(gba);