libretro / gambatte-libretro

Hard fork of Gambatte to the libretro API.
http://sourceforge.net/projects/gambatte/
GNU General Public License v2.0
104 stars 78 forks source link

RETRO_ENVIRONMENT_SET_MEMORY_MAPS incorrect for GB #146

Closed Jamiras closed 4 years ago

Jamiras commented 4 years ago

According to the libretro documentation, a length of 0 in a retro_memory_descriptor implies the length from the select and disconnect maps:

Can be zero, in which case it's assumed to be infinite (as limited by 'select' and 'disconnect')

For non-GBC mode, length is set to 0, but select is left at 0xFFFF0000, so the length is implied to be 0x10000. https://github.com/libretro/gambatte-libretro/blob/4d9ad7b29946ec0a914b2d6a735b6c2704ed1f23/libgambatte/libretro/libretro.cpp#L1010

Since ptr is also non-null, this makes it appear as if there are 64KB of data being exposed at $10000 for basic GameBoy games. Trying to read beyond 0x5FB7 bytes into the block causes an access violation.

I see a few possible solutions to address this. 1) The preferred solution would be to exclude the descriptor entirely. 2) Move the offending descriptor to the end of the array and send 1 less item in num_descriptors. 3) Set ptr to NULL. This indicates there isn't any usable data at the address, but the documentation says "no flags should be set if the pointer is NULL", so the flags column should also be updated. 4) Set select to 0xFFFFFFFF. This would effectively calculate the length to be 1 (there's only one address that matches any given address where all 32 bits are unique), and there is at least one valid byte in the pointed-at data. This is the least desirable solution, as the byte doesn't really exist, but would appear to exist.

negativeExponent commented 4 years ago

see if PR fixes your issue. SRAM and GBC pointers are skipped in memmap struct if they are unavailable.

Jamiras commented 4 years ago

Changes are behaving as expected. GB game returns fewer memory descriptors than GBC game. The block starting at $10000 is no longer present.