Initial halt/stop during DMA support
This commit is contained in:
parent
cce36f1754
commit
ee03b1e433
@ -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)) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user