Continue implementing IRQs
Jeffrey Pfau jeffrey@endrift.com
Tue, 16 Apr 2013 07:42:20 -0700
3 files changed,
48 insertions(+),
1 deletions(-)
M
src/gba/gba-io.c
→
src/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.c
→
src/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.h
→
src/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);