mupen64plus / mupen64plus-core

Core module of the Mupen64Plus project
1.29k stars 257 forks source link

Cartridges above 64 MB in size? #997

Open Chlorobyte-but-real opened 1 year ago

Chlorobyte-but-real commented 1 year ago
static uint32_t rom_address(uint32_t address)
{
    return (address & 0x03fffffc);
}

ROM accesses currently seem to wrap around at every 64 MB increment.

We have encountered an issue while working on a romhack that pushes the ROM to 96 MB, where any read above the 64 MB barrier would access the beginning of ROM instead.

The goal of this issue isn't necessarily to get funny big romhack to work. Rather, it is to confirm whether Mupen's behavior is accurate to the console or not. This & operation has been around since the very first commit on Git, and there is no information on why it was necessarily capped to wrap around like this.

A previous hack we released pushed just slightly past 64 MB by a mere 16 bytes. We would then perform a DMA copy right at the end of the ROM. Testers reported a black screen on console without the crash handler popping up. This was only on console - all emulators (HLE, LLE) ran the game fine -, so I suspect it might have been the Everdrive's DRAM being limited to 64 MB, and thus it either having no idea how to handle an out of bounds read, or just outright giving up before even launching the game. Nothing else relevant has changed compared to a prior version, which didn't push 64 MB, and ran just fine. One thing's for sure - Everdrives cannot be used to run >64 MB ROMs.

We should properly test ROM reads on console with a >64MB cartridge somehow. I could not find any information on a 64 MB hard cap on cartridge sizes on N64.

Jj0YzL5nvJ commented 1 year ago

685

Test ROM? Patch?

Chlorobyte-but-real commented 1 year ago

Whipped up a test ROM. Use left and right to scroll through the images, and watch it loop back to the start of the ROM at 64MB on Mupen. It does the same on Project64, but only after the end of the ROM.

Of course, would be better to get console verification on which or what behavior would be correct.

dmatest.zip

For my first homebrew, I decided to simply software render stuff, so accurate framebuffer emulation might be required.

fraser125 commented 1 year ago

According to the creator of the 64Drive, the N64 hardware supports 240 MB ROM's. The tone of this response was that this is a conservative value, that is roundish and easy to achieve. The actual max ROM size could be as high as 252 MB (not as round).

Showing my work: Cartridge ROM Range N64 Memory Map 0x10000000 | 0x1FBFFFFF = 264,241,152 / 1024 / 1024 = 252 MB

The PI DMA Cartridge address field is 32-bits so no limitation there, and the RAM destination has an interesting maximum of 16 MB.

The 64Drive v2 has 256 MB of RAM to hold the ROM's 64Drive Features so this would be the only way to play a ROM over 64 MB on an N64 console.

therealteamplayer commented 1 year ago

Would it be possible to add an option to alter this behaviour, since there are romhacks larger than 64MB that cannot be run?

kargaroc commented 11 months ago

If the 64MB "limit" doesn't exist on real hardware, and there's no unholy hacks that depend on it being limited, then I don't see a reason for an option.

kargaroc commented 9 months ago

And of course like everyone's been saying, there are romhacks that require larger sizes than 64MB, which unless this gets fixed the only way to play them is on a ridiculously expensive flashcart, or maybe the Windows-only X86-only emulator.

rasky commented 6 months ago

There is actually no 64 or 252 MiB limit for a N64 cartridge. The PI bus is based on a full 32-bit address space (that can be accessed via PI DMA), so a cartridge could expose up to 4 GiB of data (without special hardware bank switchers).

It's true that only 252 MiB of it would be memory mapped in the 0x10000000 - 0x1FBFFFFF range, but CPU access to ROM is very very rare and almost never used for speed reason. Almost all accesses happen via PI DMA, and PI DMA can address up to 4 GiB.

I'll also notice that other areas of the PI bus are memory mapped. For instance physical addresses 0x20000000 - 0x7FFFFFFF are mapped to the PI bus as well (1.5 GiB of data), and they are perfectly accessible from the VR4300 in 64-bit mode (using virtual addresses such as 0x9000_0000_nnnn_nnnn). This is also correctly emulated by modern emulators like Ares.

References: https://n64brew.dev/wiki/FAQ#What_is_the_maximum_cartridge_size_(ROM)_supported_by_a_Nintendo_64? https://n64brew.dev/wiki/Memory_map#Physical_Memory_Map