Move halting code out from below the ARM emulator

This commit is contained in:
Jeffrey Pfau 2013-11-03 23:25:57 -08:00
parent 66ee98513f
commit 3b74b61862
2 changed files with 40 additions and 49 deletions

View File

@ -152,37 +152,47 @@ void GBABoardReset(struct ARMBoard* board) {
static void GBAProcessEvents(struct ARMBoard* board) { static void GBAProcessEvents(struct ARMBoard* board) {
struct GBABoard* gbaBoard = (struct GBABoard*) board; struct GBABoard* gbaBoard = (struct GBABoard*) board;
int32_t cycles = board->cpu->cycles; do {
int32_t nextEvent = INT_MAX; int32_t cycles = board->cpu->cycles;
int32_t testEvent; int32_t nextEvent = INT_MAX;
int32_t testEvent;
if (gbaBoard->p->springIRQ) { if (gbaBoard->p->springIRQ) {
ARMRaiseIRQ(&gbaBoard->p->cpu); ARMRaiseIRQ(&gbaBoard->p->cpu);
gbaBoard->p->springIRQ = 0; gbaBoard->p->springIRQ = 0;
} }
testEvent = GBAVideoProcessEvents(&gbaBoard->p->video, cycles); testEvent = GBAVideoProcessEvents(&gbaBoard->p->video, cycles);
if (testEvent < nextEvent) { if (testEvent < nextEvent) {
nextEvent = testEvent; nextEvent = testEvent;
} }
testEvent = GBAAudioProcessEvents(&gbaBoard->p->audio, cycles); testEvent = GBAAudioProcessEvents(&gbaBoard->p->audio, cycles);
if (testEvent < nextEvent) { if (testEvent < nextEvent) {
nextEvent = testEvent; nextEvent = testEvent;
} }
testEvent = GBAMemoryProcessEvents(&gbaBoard->p->memory, cycles); testEvent = GBAMemoryProcessEvents(&gbaBoard->p->memory, cycles);
if (testEvent < nextEvent) { if (testEvent < nextEvent) {
nextEvent = testEvent; nextEvent = testEvent;
} }
testEvent = GBATimersProcessEvents(gbaBoard->p, cycles); testEvent = GBATimersProcessEvents(gbaBoard->p, cycles);
if (testEvent < nextEvent) { if (testEvent < nextEvent) {
nextEvent = testEvent; nextEvent = testEvent;
} }
board->cpu->cycles = 0; board->cpu->cycles = 0;
board->cpu->nextEvent = nextEvent; 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) { static int32_t GBATimersProcessEvents(struct GBA* gba, int32_t cycles) {
@ -456,28 +466,9 @@ void GBATestIRQ(struct ARMBoard* board) {
} }
} }
int GBAWaitForIRQ(struct GBA* gba) { void GBAHalt(struct GBA* gba) {
int irqs = gba->memory.io[REG_IF >> 1]; gba->cpu.cycles = gba->cpu.nextEvent;
int newIRQs = 0; gba->halted = 1;
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 GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) { void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) {

View File

@ -85,6 +85,7 @@ struct GBA {
unsigned enable : 1; unsigned enable : 1;
} timers[4]; } timers[4];
int halted;
int springIRQ; int springIRQ;
int* keySource; int* keySource;
struct GBARotationSource* rotationSource; struct GBARotationSource* rotationSource;
@ -127,8 +128,7 @@ void GBAWriteIE(struct GBA* gba, uint16_t value);
void GBAWriteIME(struct GBA* gba, uint16_t value); void GBAWriteIME(struct GBA* gba, uint16_t value);
void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq); void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq);
void GBATestIRQ(struct ARMBoard* board); void GBATestIRQ(struct ARMBoard* board);
int GBAWaitForIRQ(struct GBA* gba); void GBAHalt(struct GBA* gba);
int GBAHalt(struct GBA* gba);
void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger); void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger);