-
Notifications
You must be signed in to change notification settings - Fork 143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Increase SNES max rom size #172
Comments
The value is low because of limited memory yes and it took a lot of work to even get to that mere 2.25MB. I think it's a good idea to support larger sizes but I don't want to make it configurable (unless we have no other choice)... The largest commercial ROM seems to be 6MB, max addressable is 8MB, and Snes9x originally had a 12MB MAX_ROM_SIZE (for reasons that are irrelevant to us). So I guess any of 4/6/8 would be reasonable upper limits. But finding the lower limit is what we're concerned with. A few ideas:
But look how small the change would be: for (size_t AllocSize = 0x800000; AllocSize > 0 && !Memory.ROM; AllocSize /= 2)
{
Memory.ROM_AllocSize = AllocSize + 0x40000 + 0x200;
Memory.ROM = (uint8_t*) calloc(Memory.ROM_AllocSize, 1);
} Let me know what you think! |
It works fine indeed ! bool S9xInitMemory(void)
{
Memory.RAM = (uint8_t*) calloc(RAM_SIZE, 1);
Memory.SRAM = (uint8_t*) calloc(SRAM_SIZE, 1);
Memory.VRAM = (uint8_t*) calloc(VRAM_SIZE, 1);
Memory.FillRAM = (uint8_t*) calloc(0x8000, 1);
Memory.Map = (uint8_t**)calloc(MEMMAP_NUM_BLOCKS, sizeof(uint8_t*));
Memory.MapInfo = (SMapInfo*)calloc(MEMMAP_NUM_BLOCKS, sizeof(SMapInfo));
IPPU.ScreenColors = (uint16_t *)calloc(256 * 9, sizeof(uint16_t));
IPPU.DirectColors = IPPU.ScreenColors + 256;
IPPU.TileCache = (uint8_t*) calloc(MAX_2BIT_TILES, 128);
IPPU.TileCached = (uint8_t*) calloc(MAX_2BIT_TILES, 1);
bytes0x2000 = (uint8_t *)calloc(0x2000, 1);
// example list of "standard" rom sizes
size_t AllocSizes[] = {0x800000, 0x600000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000};
for (int i = 0; i < sizeof(AllocSizes) && !Memory.ROM; i += 1)
{
Memory.ROM_AllocSize = AllocSizes[i] + 0x200;
Memory.ROM = (uint8_t*) calloc(Memory.ROM_AllocSize, 1);
}
if (!Memory.RAM || !Memory.SRAM || !Memory.VRAM || !Memory.ROM || !Memory.Map || !Memory.MapInfo
|| !IPPU.ScreenColors || !IPPU.TileCache || !IPPU.TileCached || !bytes0x2000)
{
S9xDeinitMemory();
return false;
}
return true;
} solution 2 bool S9xInitMemory(const char* filename)
{
size_t TotalFileSize = 0;
FILE *fp;
Memory.RAM = (uint8_t*) calloc(RAM_SIZE, 1);
Memory.SRAM = (uint8_t*) calloc(SRAM_SIZE, 1);
Memory.VRAM = (uint8_t*) calloc(VRAM_SIZE, 1);
Memory.FillRAM = (uint8_t*) calloc(0x8000, 1);
Memory.Map = (uint8_t**)calloc(MEMMAP_NUM_BLOCKS, sizeof(uint8_t*));
Memory.MapInfo = (SMapInfo*)calloc(MEMMAP_NUM_BLOCKS, sizeof(SMapInfo));
IPPU.ScreenColors = (uint16_t *)calloc(256 * 9, sizeof(uint16_t));
IPPU.DirectColors = IPPU.ScreenColors + 256;
IPPU.TileCache = (uint8_t*) calloc(MAX_2BIT_TILES, 128);
IPPU.TileCached = (uint8_t*) calloc(MAX_2BIT_TILES, 1);
bytes0x2000 = (uint8_t *)calloc(0x2000, 1);
if (Memory.ROM_Offset)
{
Memory.ROM -= Memory.ROM_Offset;
Memory.ROM_Offset = 0;
}
if ((fp = fopen(filename, "rb")))
{
fseek(fp, 0, SEEK_END);
TotalFileSize = ftell(fp);
fclose(fp);
}
else
{
printf("Failed to open %s\n", filename);
return false;
}
Memory.ROM_AllocSize = TotalFileSize + 0x200;
Memory.ROM = (uint8_t*) calloc(Memory.ROM_AllocSize, 1);
if(!Memory.ROM){
RG_LOGE("ROM too big for available memory");
S9xDeinitMemory();
return false;
}
if (!Memory.RAM || !Memory.SRAM || !Memory.VRAM || !Memory.Map || !Memory.MapInfo
|| !IPPU.ScreenColors || !IPPU.TileCache || !IPPU.TileCached || !bytes0x2000)
{
S9xDeinitMemory();
return false;
}
return true;
} edit: after implementing second method, 6MB roms launch and we have this RAM left |
Solution 1 is interesting (though your usage of sizeof makes you go out of the array) and might indeed be better than plain arithmetic. Solution 2 is a no-go because it won't work with zip files, which are loaded outside snes9x and much later in the process :(. I'll play around with solution 1 as well as the solutions I've proposed to see what works the best across all possible RAM configurations I have to support. But that might take some time, so I'll also add dumb support for 4MB ROMs right now to be sure it's part of the next release. |
Currently the max rom size for SNES roms is 2.4MB or
Ox240000
The problem is that lot of roms are bigger than that so I increased it to 4MB or 0x400000 and It seems to work fine on the esp32-s3 with 8MB PSRAM.
I was wondering why this value was so low in the beginning (I guess that is because some modules have only 4MB PSRAM) and if it would be possible to add an option to the target config file or directly change it for all targets
The text was updated successfully, but these errors were encountered: