Skip to content

Gambatte emu.frameadvance() + "Equal Length Frames" causing callbacks to run during DMA #3711

Description

@zig-for

Summary

When running with "Equal Length Frames", calling emu.frameadvance can lead to lua running during a DMA operation. This will lead to garbage WRAM reads (open bus?) when doing a general "System Bus" read. See https://gbdev.io/pandocs/OAM_DMA_Transfer.html for a vague idea of what's happening. This may be desired behavior for some applications, but is probably unexpected for most users/script authors. I specifically saw this behavior in Link's Awakening DX.

In my specific case this causes issues with doing networked reads over RAM. I'm aware there are several workarounds:

  1. Don't use that setting (unfortunately many of the users of my script use it for better audio)
  2. Register a memoryexecute handler on the vblank handler (what I've done)
  3. Translate between RAM addresses and system domains (annoying because I'm told Sameboy and Gambatte have different domain names nobody wants to do math on memory addresses in lua)

This was repro'd specifically on 2.8, but I've had reports of 2.9 as well and can repro there if desired. This could either be regarded as a BizHawk bug or a Gambatte bug, I'm happy to report to Gambatte, if given a url. I also understand if this is closed as expected behavior - technically it is "correct" by some reading of Bizhawk's docs and of the Gambatte setting description. I'm not sure what the fix here would be. Possibilities:

  1. Sound resampling for Gambatte so that the option isn't needed (unlikely)
  2. Skip lua callbacks if a DMA is in progress (might not be desired)
  3. Attempt to run forward a bit more if DMA is in progress (??)

Repro

  1. Ensure "Equal Length Frames" is set in Gambatte
  2. Load up Link's Awakening DX in Gambatte
  3. Load up this script
while true do
    local sb = memory.read_bytes_as_array(0xC0FB, 4, "System Bus")
    local wr = memory.read_bytes_as_array(0x0FB, 4, "WRAM")

    if sb[1] ~= wr[1] then
        print("Hit error:")
        print(sb)
        print(wr)

        local pc = emu.getregister('PC')
        print(string.format("Bad PC: %04X", pc))
    end
    
    emu.frameadvance()
end
  1. Exit Tarin's house, go walk around opening and closing the menu and doing screen transitions

Output

"1": "120"
"2": "120"
"3": "120"
"4": "120"

"1": "0"
"2": "0"
"3": "0"
"4": "0"

Bad PC: FFC6

Host env.

  • BizHawk 2.8, Win64
  • Reports on 2.9, haven't personally reproduced but can if needed

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions