Implement IRQs

This commit is contained in:
Jeffrey Pfau 2013-04-16 07:50:34 -07:00
parent 2da11dd523
commit 2d0c3bf275
3 changed files with 23 additions and 3 deletions

View File

@ -111,6 +111,25 @@ void ARMReset(struct ARMCore* cpu) {
cpu->board->reset(cpu->board); cpu->board->reset(cpu->board);
} }
void ARMRaiseIRQ(struct ARMCore* cpu) {
if (cpu->cpsr.i) {
return;
}
union PSR cpsr = cpu->cpsr;
int instructionWidth;
if (cpu->executionMode == MODE_THUMB) {
instructionWidth = WORD_SIZE_THUMB;
} else {
instructionWidth = WORD_SIZE_ARM;
}
ARMSetPrivilegeMode(cpu, MODE_IRQ);
cpu->spsr = cpsr;
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM;
cpu->gprs[ARM_PC] = BASE_IRQ + WORD_SIZE_ARM;
_ARMSetMode(cpu, MODE_ARM);
cpu->cpsr.i = 1;
}
void ARMRun(struct ARMCore* cpu) { void ARMRun(struct ARMCore* cpu) {
if (cpu->executionMode == MODE_THUMB) { if (cpu->executionMode == MODE_THUMB) {
ThumbStep(cpu); ThumbStep(cpu);

View File

@ -121,6 +121,7 @@ void ARMAssociateBoard(struct ARMCore* cpu, struct ARMBoard* board);
void ARMReset(struct ARMCore* cpu); void ARMReset(struct ARMCore* cpu);
void ARMSetPrivilegeMode(struct ARMCore*, enum PrivilegeMode); void ARMSetPrivilegeMode(struct ARMCore*, enum PrivilegeMode);
void ARMRaiseIRQ(struct ARMCore*);
void ARMRun(struct ARMCore* cpu); void ARMRun(struct ARMCore* cpu);

View File

@ -109,13 +109,13 @@ void GBAWriteIE(struct GBA* gba, uint16_t value) {
} }
if (gba->memory.io[REG_IME >> 1] && value & gba->memory.io[REG_IF >> 1]) { if (gba->memory.io[REG_IME >> 1] && value & gba->memory.io[REG_IF >> 1]) {
//ARMRaiseIRQ(&gba.cpu); ARMRaiseIRQ(&gba->cpu);
} }
} }
void GBAWriteIME(struct GBA* gba, uint16_t value) { void GBAWriteIME(struct GBA* gba, uint16_t value) {
if (value && gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1]) { if (value && gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1]) {
//ARMRaiseIRQ(&gba.cpu); ARMRaiseIRQ(&gba->cpu);
} }
} }
@ -123,7 +123,7 @@ void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq) {
gba->memory.io[REG_IF >> 1] |= 1 << irq; gba->memory.io[REG_IF >> 1] |= 1 << irq;
if (gba->memory.io[REG_IME >> 1] && (gba->memory.io[REG_IE >> 1] & 1 << irq)) { if (gba->memory.io[REG_IME >> 1] && (gba->memory.io[REG_IE >> 1] & 1 << irq)) {
//ARMRaiseIRQ(); ARMRaiseIRQ(&gba->cpu);
} }
} }