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) {
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, ...) {

View File

@ -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);