mirror of https://github.com/mgba-emu/mgba.git
GB: Fix HALT
This commit is contained in:
parent
6fb8e296d4
commit
862e41ad6b
55
src/gb/gb.c
55
src/gb/gb.c
|
@ -106,6 +106,7 @@ void GBInterruptHandlerInit(struct LR35902InterruptHandler* irqh) {
|
|||
irqh->processEvents = GBProcessEvents;
|
||||
irqh->setInterrupts = GBSetInterrupts;
|
||||
irqh->hitStub = GBHitStub;
|
||||
irqh->halt = GBHalt;
|
||||
}
|
||||
|
||||
void GBReset(struct LR35902Core* cpu) {
|
||||
|
@ -133,13 +134,15 @@ void GBReset(struct LR35902Core* cpu) {
|
|||
}
|
||||
|
||||
void GBUpdateIRQs(struct GB* gb) {
|
||||
if (!gb->memory.ime) {
|
||||
return;
|
||||
}
|
||||
int irqs = gb->memory.ie & gb->memory.io[REG_IF];
|
||||
if (!irqs) {
|
||||
return;
|
||||
}
|
||||
gb->cpu->halted = false;
|
||||
|
||||
if (!gb->memory.ime) {
|
||||
return;
|
||||
}
|
||||
|
||||
gb->cpu->irqh.setInterrupts(gb->cpu, false);
|
||||
if (irqs & (1 << GB_IRQ_VBLANK)) {
|
||||
|
@ -170,27 +173,33 @@ void GBUpdateIRQs(struct GB* gb) {
|
|||
|
||||
void GBProcessEvents(struct LR35902Core* cpu) {
|
||||
struct GB* gb = (struct GB*) cpu->master;
|
||||
int32_t cycles = cpu->nextEvent;
|
||||
int32_t nextEvent = INT_MAX;
|
||||
int32_t testEvent;
|
||||
do {
|
||||
int32_t cycles = cpu->nextEvent;
|
||||
int32_t nextEvent = INT_MAX;
|
||||
int32_t testEvent;
|
||||
|
||||
testEvent = GBVideoProcessEvents(&gb->video, cycles);
|
||||
if (testEvent < nextEvent) {
|
||||
nextEvent = testEvent;
|
||||
}
|
||||
testEvent = GBVideoProcessEvents(&gb->video, cycles);
|
||||
if (testEvent < nextEvent) {
|
||||
nextEvent = testEvent;
|
||||
}
|
||||
|
||||
testEvent = GBTimerProcessEvents(&gb->timer, cycles);
|
||||
if (testEvent < nextEvent) {
|
||||
nextEvent = testEvent;
|
||||
}
|
||||
testEvent = GBTimerProcessEvents(&gb->timer, cycles);
|
||||
if (testEvent < nextEvent) {
|
||||
nextEvent = testEvent;
|
||||
}
|
||||
|
||||
testEvent = GBMemoryProcessEvents(gb, cycles);
|
||||
if (testEvent < nextEvent) {
|
||||
nextEvent = testEvent;
|
||||
}
|
||||
testEvent = GBMemoryProcessEvents(gb, cycles);
|
||||
if (testEvent < nextEvent) {
|
||||
nextEvent = testEvent;
|
||||
}
|
||||
|
||||
cpu->cycles -= cycles;
|
||||
cpu->nextEvent = nextEvent;
|
||||
cpu->cycles -= cycles;
|
||||
cpu->nextEvent = nextEvent;
|
||||
|
||||
if (cpu->halted) {
|
||||
cpu->cycles = cpu->nextEvent;
|
||||
}
|
||||
} while (cpu->cycles >= cpu->nextEvent);
|
||||
}
|
||||
|
||||
void GBSetInterrupts(struct LR35902Core* cpu, bool enable) {
|
||||
|
@ -199,6 +208,12 @@ void GBSetInterrupts(struct LR35902Core* cpu, bool enable) {
|
|||
GBUpdateIRQs(gb);
|
||||
}
|
||||
|
||||
void GBHalt(struct LR35902Core* cpu) {
|
||||
struct GB* gb = (struct GB*) cpu->master;
|
||||
cpu->cycles = cpu->nextEvent;
|
||||
cpu->halted = true;
|
||||
}
|
||||
|
||||
void GBHitStub(struct LR35902Core* cpu) {
|
||||
// TODO
|
||||
//printf("Hit stub at address %04X\n", cpu->pc);
|
||||
|
|
|
@ -84,8 +84,8 @@ void GBDestroy(struct GB* gb);
|
|||
void GBReset(struct LR35902Core* cpu);
|
||||
|
||||
void GBUpdateIRQs(struct GB* gb);
|
||||
void GBHalt(struct GB* gb);
|
||||
void GBStop(struct GB* gb);
|
||||
void GBHalt(struct LR35902Core* cpu);
|
||||
void GBStop(struct LR35902Core* cpu);
|
||||
|
||||
struct VFile;
|
||||
bool GBLoadROM(struct GB* gb, struct VFile* vf, struct VFile* sav, const char* fname);
|
||||
|
|
|
@ -730,7 +730,7 @@ DEFINE_INSTRUCTION_LR35902(RRCA_,
|
|||
|
||||
DEFINE_INSTRUCTION_LR35902(DI, cpu->irqh.setInterrupts(cpu, false));
|
||||
DEFINE_INSTRUCTION_LR35902(EI, cpu->irqh.setInterrupts(cpu, true));
|
||||
DEFINE_INSTRUCTION_LR35902(HALT, cpu->cycles = cpu->nextEvent);
|
||||
DEFINE_INSTRUCTION_LR35902(HALT, cpu->irqh.halt(cpu));
|
||||
|
||||
DEFINE_INSTRUCTION_LR35902(RST00, LR35902RaiseIRQ(cpu, 0x00));
|
||||
DEFINE_INSTRUCTION_LR35902(RST08, LR35902RaiseIRQ(cpu, 0x08));
|
||||
|
|
|
@ -63,6 +63,7 @@ struct LR35902InterruptHandler {
|
|||
void (*reset)(struct LR35902Core* cpu);
|
||||
void (*processEvents)(struct LR35902Core* cpu);
|
||||
void (*setInterrupts)(struct LR35902Core* cpu, bool enable);
|
||||
void (*halt)(struct LR35902Core* cpu);
|
||||
|
||||
void (*hitStub)(struct LR35902Core* cpu);
|
||||
};
|
||||
|
@ -113,7 +114,7 @@ struct LR35902Core {
|
|||
int32_t cycles;
|
||||
int32_t nextEvent;
|
||||
enum LR35902ExecutionState executionState;
|
||||
int halted;
|
||||
bool halted;
|
||||
|
||||
uint8_t bus;
|
||||
bool condition;
|
||||
|
|
Loading…
Reference in New Issue