Skip to content

Commit

Permalink
gba: reset prefetch buffer on ROM accesses from CPU (#1377)
Browse files Browse the repository at this point in the history
According to NanoBoyAdvance author fleroviux, the prefetch buffer should
be reset on any ROM accesses from the CPU or DMA. This PR implements
this behaviour for CPU ROM accesses. This allows ares to pass 1760/2020
of the timing tests in the mGBA test suite (up from 1608/2020).

Allowing DMA ROM accesses to clear the prefetch buffer seems to worsen
timings at the moment, possibly due to some other timing issues that
also come into effect in these situations. I've left comments to make a
note of the issue, so that resetting the prefetch buffer on ROM accesses
from DMA can be implemented once it becomes beneficial to do so.
  • Loading branch information
png183 authored Jan 27, 2024
1 parent 527aaef commit e8f38d1
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 8 deletions.
4 changes: 2 additions & 2 deletions ares/gba/cpu/bus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ auto CPU::get(u32 mode, n32 address) -> n32 {
word = prefetchRead();
if(mode & Word) word |= prefetchRead() << 16;
} else {
if(!context.dmaActive) prefetchWait();
if(!context.dmaActive) prefetchReset(); //todo: Prefetch buffer should also be reset when DMA accesses ROM
step(clocks - 1);
word = cartridge.read(mode, address);
step(1);
Expand All @@ -42,7 +42,7 @@ auto CPU::set(u32 mode, n32 address, n32 word) -> void {
if(address >= 0x1000'0000) {
prefetchStep(clocks);
} else if(address & 0x0800'0000) {
if(!context.dmaActive) prefetchWait();
if(!context.dmaActive) prefetchReset(); //todo: Prefetch buffer should also be reset when DMA accesses ROM
step(clocks);
cartridge.write(mode, address, word);
} else {
Expand Down
2 changes: 1 addition & 1 deletion ares/gba/cpu/cpu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ struct CPU : ARM7TDMI, Thread, IO {
//prefetch.cpp
auto prefetchSync(n32 address) -> void;
auto prefetchStep(u32 clocks) -> void;
auto prefetchWait() -> void;
auto prefetchReset() -> void;
auto prefetchRead() -> n16;

//bus.cpp
Expand Down
8 changes: 3 additions & 5 deletions ares/gba/cpu/prefetch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ auto CPU::prefetchStep(u32 clocks) -> void {
}
}

auto CPU::prefetchWait() -> void {
if(!wait.prefetch || context.dmaActive || prefetch.full()) return;

prefetchStep(prefetch.wait);
prefetch.wait = _wait(Half | Nonsequential, prefetch.load);
auto CPU::prefetchReset() -> void {
prefetch.addr = 0;
prefetch.load = 0;
}

auto CPU::prefetchRead() -> n16 {
Expand Down

0 comments on commit e8f38d1

Please sign in to comment.