diff --git a/src/gba/gba.c b/src/gba/gba.c index 37a90111a..0033e3490 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -37,6 +37,8 @@ void GBAInit(struct GBA* gba) { gba->video.p = gba; GBAVideoInit(&gba->video); + gba->springIRQ = 0; + ARMReset(&gba->cpu); } @@ -127,6 +129,52 @@ void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq) { } } +void GBAPollNextEvent(struct GBA* gba) { + int32_t nextEvent = gba->video.nextEvent; + + gba->cpu.nextEvent = nextEvent; +} + +int GBATestIRQ(struct GBA* gba) { + if (gba->memory.io[REG_IME >> 1] && gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1]) { + gba->springIRQ = 1; + gba->cpu.nextEvent = gba->cpu.cycles; + return 1; + } + return 0; +} + +int GBAWaitForIRQ(struct GBA* gba) { + int irqPending = GBATestIRQ(gba) || gba->video.hblankIRQ || gba->video.vblankIRQ || gba->video.vcounterIRQ; + /*if (this.timersEnabled) { + timer = this.timers[0]; + irqPending = irqPending || timer.doIrq; + timer = this.timers[1]; + irqPending = irqPending || timer.doIrq; + timer = this.timers[2]; + irqPending = irqPending || timer.doIrq; + timer = this.timers[3]; + irqPending = irqPending || timer.doIrq; + }*/ + if (!irqPending) { + return 0; + } + + while (1) { + GBAPollNextEvent(gba); + + if (gba->cpu.nextEvent == INT_MAX) { + return 0; + } else { + gba->cpu.cycles = gba->cpu.nextEvent; + GBAProcessEvents(&gba->board.d); + if (gba->memory.io[REG_IF >> 1]) { + return 1; + } + } + } +} + void GBALog(int level, const char* format, ...) { va_list args; va_start(args, format); diff --git a/src/gba/gba.h b/src/gba/gba.h index 7f9fd1e9c..c8c460ba4 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h @@ -45,6 +45,8 @@ struct GBA { struct ARMDebugger* debugger; + int springIRQ; + enum GBAError errno; const char* errstr; }; @@ -61,6 +63,9 @@ 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 GBAPollNextEvent(struct GBA* gba); +int GBATestIRQ(struct GBA* gba); +int GBAWaitForIRQ(struct GBA* gba); void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger);