Starting to remove the delayed interrupts hack – done for timer interrupt, broken for display interrupts

This commit is contained in:
Lior Halphon 2018-02-23 15:33:44 +02:00
parent c48097a484
commit 42ab746a66
6 changed files with 36 additions and 23 deletions

View File

@ -661,6 +661,8 @@ static void update_display_state(GB_gameboy_t *gb, uint8_t cycles)
void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
{
if (gb->display_hack == 1) return;
if (gb->display_hack == 2) cycles *= 2;
update_display_state(gb, cycles);
if (gb->disable_rendering) {
return;

View File

@ -340,6 +340,7 @@ struct GB_gameboy_internal_s {
uint16_t serial_length;
uint8_t future_interrupts; /* Interrupts can occur in any T-cycle. Some timings result in different interrupt
timing when the CPU is in halt mode, and might also affect the DI instruction. */
uint8_t display_hack; // Temporary hack until the display is rewritten to operate in T-cycle rates;
);
/* APU */

View File

@ -484,7 +484,9 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
return;
case GB_IO_DIV:
gb->div_state = 0; // Reset the div state machine
/* Reset the div state machine */
gb->div_state = 0;
gb->div_cycles = 0;
return;
case GB_IO_JOYP:

View File

@ -96,13 +96,11 @@ static void GB_ir_run(GB_gameboy_t *gb)
static void advance_tima_state_machine(GB_gameboy_t *gb)
{
gb->io_registers[GB_IO_IF] |= gb->future_interrupts & 4;
gb->future_interrupts &= ~4;
if (gb->tima_reload_state == GB_TIMA_RELOADED) {
gb->tima_reload_state = GB_TIMA_RUNNING;
}
else if (gb->tima_reload_state == GB_TIMA_RELOADING) {
gb->future_interrupts |= 4;
gb->io_registers[GB_IO_IF] |= 4;
gb->tima_reload_state = GB_TIMA_RELOADED;
}
}
@ -140,14 +138,16 @@ static void GB_timers_run(GB_gameboy_t *gb, uint8_t cycles)
{
GB_STATE_MACHINE(gb, div, cycles) {
GB_STATE(gb, div, 1);
GB_STATE(gb, div, 2);
}
GB_set_internal_div_counter(gb, 0);
GB_SLEEP(gb, div, 1, 2);
while (true) {
advance_tima_state_machine(gb);
GB_set_internal_div_counter(gb, gb->div_counter + 4);
gb->apu.apu_cycles += 4 << !gb->cgb_double_speed;
GB_SLEEP(gb, div, 1, 4);
GB_SLEEP(gb, div, 2, 4);
}
}

View File

@ -38,6 +38,6 @@ switch ((gb)->unit##_state)
#define GB_STATE(gb, unit, state) case state: goto unit##state
#define GB_UNIT(unit) uint32_t unit##_cycles, unit##_state
#define GB_UNIT(unit) int32_t unit##_cycles, unit##_state
#endif /* timing_h */

View File

@ -1337,23 +1337,29 @@ static GB_opcode_t *opcodes[256] = {
};
void GB_cpu_run(GB_gameboy_t *gb)
{
if (gb->hdma_on) {
GB_advance_cycles(gb, 4);
return;
}
gb->vblank_just_occured = false;
if (gb->halted) {
gb->display_hack = 1;
GB_advance_cycles(gb, 2);
}
uint8_t interrupt_queue = gb->interrupt_enable & gb->io_registers[GB_IO_IF] & 0x1F;
if (!gb->halted) {
interrupt_queue |= gb->future_interrupts & gb->interrupt_enable;
if (gb->halted) {
gb->display_hack = 2;
GB_advance_cycles(gb, 2);
gb->display_hack = 0;
}
gb->io_registers[GB_IO_IF] |= gb->future_interrupts;
gb->future_interrupts = 0;
if (interrupt_queue) {
gb->halted = false;
}
if (gb->hdma_on) {
GB_advance_cycles(gb, 4);
return;
}
bool effecitve_ime = gb->ime;
if (gb->ime_toggle) {
@ -1361,11 +1367,15 @@ void GB_cpu_run(GB_gameboy_t *gb)
gb->ime_toggle = false;
}
if (effecitve_ime && interrupt_queue) {
nop(gb, 0);
/* Wake up from HALT mode without calling interrupt code. */
if (gb->halted && !effecitve_ime && interrupt_queue) {
gb->halted = false;
}
/* Call interrupt */
else if (effecitve_ime && interrupt_queue) {
gb->halted = false;
uint16_t call_addr = gb->pc - 1;
GB_advance_cycles(gb, 8);
GB_advance_cycles(gb, 12);
gb->registers[GB_REGISTER_SP] -= 2;
GB_write_memory(gb, gb->registers[GB_REGISTER_SP] + 1, (gb->pc) >> 8);
interrupt_queue = gb->interrupt_enable;
@ -1391,6 +1401,7 @@ void GB_cpu_run(GB_gameboy_t *gb)
gb->ime = false;
GB_debugger_call_hook(gb, call_addr);
}
/* Run mode */
else if(!gb->halted && !gb->stopped) {
uint8_t opcode = GB_read_memory(gb, gb->pc++);
if (gb->halt_bug) {
@ -1399,7 +1410,4 @@ void GB_cpu_run(GB_gameboy_t *gb)
}
opcodes[opcode](gb, opcode);
}
else {
GB_advance_cycles(gb, 4);
}
}