Initial halt/stop during DMA support

This commit is contained in:
Lior Halphon 2022-01-19 01:24:40 +02:00
parent cce36f1754
commit ee03b1e433
3 changed files with 16 additions and 2 deletions

View File

@ -1699,6 +1699,7 @@ bool GB_is_dma_active(GB_gameboy_t *gb)
void GB_dma_run(GB_gameboy_t *gb) void GB_dma_run(GB_gameboy_t *gb)
{ {
if (gb->dma_current_dest == 0xa1) return; if (gb->dma_current_dest == 0xa1) return;
if (unlikely(gb->halted || gb->stopped)) return;
signed cycles = gb->dma_cycles + gb->dma_cycles_modulo; signed cycles = gb->dma_cycles + gb->dma_cycles_modulo;
gb->in_dma_read = true; gb->in_dma_read = true;
while (unlikely(cycles >= 4)) { while (unlikely(cycles >= 4)) {

View File

@ -372,6 +372,11 @@ static void stop(GB_gameboy_t *gb, uint8_t opcode)
bool interrupt_pending = (gb->interrupt_enable & gb->io_registers[GB_IO_IF] & 0x1F); bool interrupt_pending = (gb->interrupt_enable & gb->io_registers[GB_IO_IF] & 0x1F);
// When entering with IF&IE, the 2nd byte of STOP is actually executed // When entering with IF&IE, the 2nd byte of STOP is actually executed
if (!exit_by_joyp) { if (!exit_by_joyp) {
if (!immediate_exit) {
// TODO: verify this!
gb->dma_cycles = 4;
GB_dma_run(gb);
}
enter_stop_mode(gb); enter_stop_mode(gb);
} }
@ -414,6 +419,9 @@ static void stop(GB_gameboy_t *gb, uint8_t opcode)
if (immediate_exit) { if (immediate_exit) {
leave_stop_mode(gb); leave_stop_mode(gb);
if (!interrupt_pending) { if (!interrupt_pending) {
// TODO: verify this!
gb->dma_cycles = 4;
GB_dma_run(gb);
gb->halted = true; gb->halted = true;
gb->just_halted = true; gb->just_halted = true;
} }
@ -1004,7 +1012,6 @@ static void halt(GB_gameboy_t *gb, uint8_t opcode)
gb->pending_cycles = 0; gb->pending_cycles = 0;
GB_advance_cycles(gb, 4); GB_advance_cycles(gb, 4);
gb->halted = true;
/* Despite what some online documentations say, the HALT bug also happens on a CGB, in both CGB and DMG modes. */ /* Despite what some online documentations say, the HALT bug also happens on a CGB, in both CGB and DMG modes. */
if (((gb->interrupt_enable & gb->io_registers[GB_IO_IF] & 0x1F) != 0)) { if (((gb->interrupt_enable & gb->io_registers[GB_IO_IF] & 0x1F) != 0)) {
if (gb->ime) { if (gb->ime) {
@ -1016,6 +1023,12 @@ static void halt(GB_gameboy_t *gb, uint8_t opcode)
gb->halt_bug = true; gb->halt_bug = true;
} }
} }
else {
// TODO: verify the timing!
gb->dma_cycles = 4;
GB_dma_run(gb);
gb->halted = true;
}
gb->just_halted = true; gb->just_halted = true;
} }

View File

@ -384,7 +384,7 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
} }
gb->apu.pcm_mask[0] = gb->apu.pcm_mask[1] = 0xFF; // Sort of hacky, but too many cross-component interactions to do it right gb->apu.pcm_mask[0] = gb->apu.pcm_mask[1] = 0xFF; // Sort of hacky, but too many cross-component interactions to do it right
// Affected by speed boost // Affected by speed boost
gb->dma_cycles += cycles; gb->dma_cycles = cycles;
timers_run(gb, cycles); timers_run(gb, cycles);
if (unlikely(!gb->stopped)) { if (unlikely(!gb->stopped)) {