all repos — mgba @ 2da11dd523543964bf3b1bf378071a815a8bf575

mGBA Game Boy Advance Emulator

Continue implementing IRQs
Jeffrey Pfau jeffrey@endrift.com
Tue, 16 Apr 2013 07:42:20 -0700
commit

2da11dd523543964bf3b1bf378071a815a8bf575

parent

4dd98f4c25e238f17df4a5ba8545218ca6d2d061

3 files changed, 48 insertions(+), 1 deletions(-)

jump to
M src/gba/gba-io.csrc/gba/gba-io.c

@@ -10,6 +10,12 @@ break;

case REG_WAITCNT: GBAAdjustWaitstates(&gba->memory, value); break; + case REG_IE: + GBAWriteIE(gba, value); + break; + case REG_IME: + GBAWriteIME(gba, value); + break; default: GBALog(GBA_LOG_STUB, "Stub I/O register write: %03x", address); break;

@@ -22,7 +28,9 @@ switch (address) {

case REG_DISPSTAT: return GBAVideoReadDISPSTAT(&gba->video); break; + case REG_IE: case REG_WAITCNT: + case REG_IME: // Handled transparently by registers break; default:
M src/gba/gba.csrc/gba/gba.c

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

#include "gba.h" #include "gba-bios.h" +#include "gba-io.h" #include "debugger.h"

@@ -86,8 +87,44 @@ gba->memory.rom = mmap(0, SIZE_CART0, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, fd, 0);

// TODO: error check } +void GBAWriteIE(struct GBA* gba, uint16_t value) { + if (value & ((1 << IRQ_TIMER0) | (1 << IRQ_TIMER1) | (1 << IRQ_TIMER2) | (1 << IRQ_TIMER3))) { + GBALog(GBA_LOG_STUB, "Timer interrupts not implemented"); + } + + if (value & (1 << IRQ_SIO)) { + GBALog(GBA_LOG_STUB, "SIO interrupts not implemented"); + } + + if (value & ((1 << IRQ_DMA0) | (1 << IRQ_DMA1) | (1 << IRQ_DMA2) | (1 << IRQ_DMA3))) { + GBALog(GBA_LOG_STUB, "DMA interrupts not implemented"); + } + + if (value & (1 << IRQ_KEYPAD)) { + GBALog(GBA_LOG_STUB, "Keypad interrupts not implemented"); + } + + if (value & (1 << IRQ_GAMEPAK)) { + GBALog(GBA_LOG_STUB, "Gamepak interrupts not implemented"); + } + + if (gba->memory.io[REG_IME >> 1] && value & gba->memory.io[REG_IF >> 1]) { + //ARMRaiseIRQ(&gba.cpu); + } +} + +void GBAWriteIME(struct GBA* gba, uint16_t value) { + if (value && gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1]) { + //ARMRaiseIRQ(&gba.cpu); + } +} + void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq) { - GBALog(GBA_LOG_STUB, "Attempting to raise IRQ"); + gba->memory.io[REG_IF >> 1] |= 1 << irq; + + if (gba->memory.io[REG_IME >> 1] && (gba->memory.io[REG_IE >> 1] & 1 << irq)) { + //ARMRaiseIRQ(); + } } void GBALog(int level, const char* format, ...) {
M src/gba/gba.hsrc/gba/gba.h

@@ -58,6 +58,8 @@

void GBABoardInit(struct GBABoard* board); void GBABoardReset(struct ARMBoard* board); +void GBAWriteIE(struct GBA* gba, uint16_t value); +void GBAWriteIME(struct GBA* gba, uint16_t value); void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq); void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger);