Skip to content

Commit

Permalink
gba: fix timing of initial DMA wait cycles (ares-emulator#1461)
Browse files Browse the repository at this point in the history
DMAs on the GBA wait for two cycles before taking control of the bus.
While ares implements this behaviour, ticking these cycles before
running DMAs causes the DMA to run early in ares when the current call
to `CPU::step()` runs for a number of cycles equal to or greater than
the number of DMA wait cycles left.

This PR addresses the issue by ticking DMA wait cycles after running all
DMAs that are currently ready, fixing several timing test cases in the
mGBA test suite, and improving timings in the [Hades DMA start delay
tests](https://github.com/hades-emu/Hades-Tests/blob/master/source/dma-start-delay.c).
  • Loading branch information
png183 authored Apr 25, 2024
1 parent de8f344 commit edf2519
Showing 1 changed file with 5 additions and 5 deletions.
10 changes: 5 additions & 5 deletions ares/gba/cpu/cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,17 @@ auto CPU::main() -> void {
auto CPU::step(u32 clocks) -> void {
if(!clocks) return;

dma[0].waiting = max(0, dma[0].waiting - (s32)clocks);
dma[1].waiting = max(0, dma[1].waiting - (s32)clocks);
dma[2].waiting = max(0, dma[2].waiting - (s32)clocks);
dma[3].waiting = max(0, dma[3].waiting - (s32)clocks);

if(!context.dmaActive) {
context.dmaActive = true;
while(dma[0].run() | dma[1].run() | dma[2].run() | dma[3].run());
context.dmaActive = false;
}

dma[0].waiting = max(0, dma[0].waiting - (s32)clocks);
dma[1].waiting = max(0, dma[1].waiting - (s32)clocks);
dma[2].waiting = max(0, dma[2].waiting - (s32)clocks);
dma[3].waiting = max(0, dma[3].waiting - (s32)clocks);

for(auto _ : range(clocks)) {
timer[0].run();
timer[1].run();
Expand Down

0 comments on commit edf2519

Please sign in to comment.