From 3b74b61862da06b71d6cb256754f48feec409f7f Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sun, 3 Nov 2013 23:25:57 -0800 Subject: [PATCH] Move halting code out from below the ARM emulator --- src/gba/gba.c | 85 +++++++++++++++++++++++---------------------------- src/gba/gba.h | 4 +-- 2 files changed, 40 insertions(+), 49 deletions(-) diff --git a/src/gba/gba.c b/src/gba/gba.c index 0bc5af8f4..f7ddfa25b 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -152,37 +152,47 @@ void GBABoardReset(struct ARMBoard* board) { static void GBAProcessEvents(struct ARMBoard* board) { struct GBABoard* gbaBoard = (struct GBABoard*) board; - int32_t cycles = board->cpu->cycles; - int32_t nextEvent = INT_MAX; - int32_t testEvent; + do { + int32_t cycles = board->cpu->cycles; + int32_t nextEvent = INT_MAX; + int32_t testEvent; - if (gbaBoard->p->springIRQ) { - ARMRaiseIRQ(&gbaBoard->p->cpu); - gbaBoard->p->springIRQ = 0; - } + if (gbaBoard->p->springIRQ) { + ARMRaiseIRQ(&gbaBoard->p->cpu); + gbaBoard->p->springIRQ = 0; + } - testEvent = GBAVideoProcessEvents(&gbaBoard->p->video, cycles); - if (testEvent < nextEvent) { - nextEvent = testEvent; - } + testEvent = GBAVideoProcessEvents(&gbaBoard->p->video, cycles); + if (testEvent < nextEvent) { + nextEvent = testEvent; + } - testEvent = GBAAudioProcessEvents(&gbaBoard->p->audio, cycles); - if (testEvent < nextEvent) { - nextEvent = testEvent; - } + testEvent = GBAAudioProcessEvents(&gbaBoard->p->audio, cycles); + if (testEvent < nextEvent) { + nextEvent = testEvent; + } - testEvent = GBAMemoryProcessEvents(&gbaBoard->p->memory, cycles); - if (testEvent < nextEvent) { - nextEvent = testEvent; - } + testEvent = GBAMemoryProcessEvents(&gbaBoard->p->memory, cycles); + if (testEvent < nextEvent) { + nextEvent = testEvent; + } - testEvent = GBATimersProcessEvents(gbaBoard->p, cycles); - if (testEvent < nextEvent) { - nextEvent = testEvent; - } + testEvent = GBATimersProcessEvents(gbaBoard->p, cycles); + if (testEvent < nextEvent) { + nextEvent = testEvent; + } - board->cpu->cycles = 0; - board->cpu->nextEvent = nextEvent; + board->cpu->cycles = 0; + board->cpu->nextEvent = nextEvent; + + if (gbaBoard->p->halted) { + gbaBoard->p->halted = !(gbaBoard->p->memory.io[REG_IF >> 1] & gbaBoard->p->memory.io[REG_IE >> 1]); + board->cpu->cycles = nextEvent; + if (nextEvent == INT_MAX) { + break; + } + } + } while (gbaBoard->p->halted); } static int32_t GBATimersProcessEvents(struct GBA* gba, int32_t cycles) { @@ -456,28 +466,9 @@ void GBATestIRQ(struct ARMBoard* board) { } } -int GBAWaitForIRQ(struct GBA* gba) { - int irqs = gba->memory.io[REG_IF >> 1]; - int newIRQs = 0; - gba->memory.io[REG_IF >> 1] = 0; - while (1) { - if (gba->cpu.nextEvent == INT_MAX) { - break; - } else { - gba->cpu.cycles = gba->cpu.nextEvent; - GBAProcessEvents(&gba->board.d); - if (gba->memory.io[REG_IF >> 1]) { - newIRQs = gba->memory.io[REG_IF >> 1]; - break; - } - } - } - gba->memory.io[REG_IF >> 1] = newIRQs | irqs; - return newIRQs; -} - -int GBAHalt(struct GBA* gba) { - return GBAWaitForIRQ(gba); +void GBAHalt(struct GBA* gba) { + gba->cpu.cycles = gba->cpu.nextEvent; + gba->halted = 1; } void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) { diff --git a/src/gba/gba.h b/src/gba/gba.h index bc3561be5..100f01766 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h @@ -85,6 +85,7 @@ struct GBA { unsigned enable : 1; } timers[4]; + int halted; int springIRQ; int* keySource; struct GBARotationSource* rotationSource; @@ -127,8 +128,7 @@ 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 GBATestIRQ(struct ARMBoard* board); -int GBAWaitForIRQ(struct GBA* gba); -int GBAHalt(struct GBA* gba); +void GBAHalt(struct GBA* gba); void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger);