BizHawk/waterbox/virtualjaguar/src/rom.cpp

137 lines
3.4 KiB
C++

//
// ROM.CPP
//
// ROM support
// by James Hammons
// (C) 2010 Underground Software
//
// JLH = James Hammons <jlhamm@acm.org>
//
// Who When What
// --- ---------- ------------------------------------------------------------
// JLH 01/16/2010 Created this log ;-)
// JLH 02/28/2010 Added functions to look inside .ZIP files and handle
// contents
// JLH 06/01/2012 Added function to check ZIP file CRCs against file DB
//
#include "rom.h"
#include <stdarg.h>
#include <string.h>
#include "crc32.h"
#include "eeprom.h"
#include "jaguar.h"
#include "memory.h"
bool JaguarLoadROM(uint8_t * buffer, uint32_t size)
{
jaguarROMSize = size;
jaguarMainROMCRC32 = crc32_calcCheckSum(buffer, jaguarROMSize);
EepromInit();
jaguarRunAddress = 0x802000;
int fileType = ParseROMType(buffer, jaguarROMSize);
jaguarCartInserted = false;
if (fileType == JST_ROM)
{
jaguarCartInserted = true;
memcpy(jagMemSpace + 0x800000, buffer, jaguarROMSize);
jaguarRunAddress = GET32(jagMemSpace, 0x800404);
return true;
}
else if (fileType == JST_ALPINE)
{
memset(jagMemSpace + 0x800000, 0xFF, 0x2000);
memcpy(jagMemSpace + 0x802000, buffer, jaguarROMSize);
SET32(jaguarMainRAM, 0x10, 0x00001000);
SET16(jaguarMainRAM, 0x1000, 0x60FE);
return true;
}
else if (fileType == JST_ABS_TYPE1)
{
uint32_t loadAddress = GET32(buffer, 0x16),
codeSize = GET32(buffer, 0x02) + GET32(buffer, 0x06);
memcpy(jagMemSpace + loadAddress, buffer + 0x24, codeSize);
jaguarRunAddress = loadAddress;
return true;
}
else if (fileType == JST_ABS_TYPE2)
{
uint32_t loadAddress = GET32(buffer, 0x28), runAddress = GET32(buffer, 0x24),
codeSize = GET32(buffer, 0x18) + GET32(buffer, 0x1C);
memcpy(jagMemSpace + loadAddress, buffer + 0xA8, codeSize);
jaguarRunAddress = runAddress;
return true;
}
else if (fileType == JST_JAGSERVER)
{
uint32_t loadAddress = GET32(buffer, 0x22), runAddress = GET32(buffer, 0x2A);
memcpy(jagMemSpace + loadAddress, buffer + 0x2E, jaguarROMSize - 0x2E);
jaguarRunAddress = runAddress;
SET32(jaguarMainRAM, 0x10, 0x00001000);
SET16(jaguarMainRAM, 0x1000, 0x60FE);
return true;
}
else if (fileType == JST_WTFOMGBBQ)
{
uint32_t loadAddress = (buffer[0x1F] << 24) | (buffer[0x1E] << 16) | (buffer[0x1D] << 8) | buffer[0x1C];
memcpy(jagMemSpace + loadAddress, buffer + 0x20, jaguarROMSize - 0x20);
jaguarRunAddress = loadAddress;
return true;
}
// We can assume we have JST_NONE at this point. :-P
return false;
}
bool AlpineLoadROM(uint8_t * buffer, uint32_t size)
{
jaguarROMSize = size;
jaguarMainROMCRC32 = crc32_calcCheckSum(buffer, jaguarROMSize);
EepromInit();
jaguarRunAddress = 0x802000;
memset(jagMemSpace + 0x800000, 0xFF, 0x2000);
memcpy(jagMemSpace + 0x802000, buffer, jaguarROMSize);
SET32(jaguarMainRAM, 0x10, 0x00001000);
SET16(jaguarMainRAM, 0x1000, 0x60FE);
return true;
}
uint32_t ParseROMType(uint8_t * buffer, uint32_t size)
{
if (buffer[0] == 0x60 && buffer[1] == 0x1B)
return JST_ABS_TYPE1;
if (buffer[0] == 0x01 && buffer[1] == 0x50)
return JST_ABS_TYPE2;
if (buffer[0] == 0x60 && buffer[1] == 0x1A)
{
if (buffer[0x1C] == 'J' && buffer[0x1D] == 'A' && buffer[0x1E] == 'G')
return JST_JAGSERVER;
else
return JST_WTFOMGBBQ;
}
if ((size % 1048576) == 0 || size == 131072)
return JST_ROM;
if (((size + 8192) % 1048576) == 0)
return JST_ALPINE;
return JST_NONE;
}