in cores/snes/memmap.cpp [2352:2752]
void CMemory::InitROM (void)
{
Settings.SuperFX = FALSE;
Settings.DSP = 0;
Settings.SA1 = FALSE;
Settings.C4 = FALSE;
Settings.SDD1 = FALSE;
Settings.SPC7110 = FALSE;
Settings.SPC7110RTC = FALSE;
Settings.OBC1 = FALSE;
Settings.SETA = 0;
Settings.SRTC = FALSE;
Settings.BS = FALSE;
Settings.MSU1 = FALSE;
SuperFX.nRomBanks = CalculatedSize >> 15;
//// Parse ROM header and read ROM informatoin
CompanyId = -1;
memset(ROMId, 0, 5);
uint8 *RomHeader = ROM + 0x7FB0;
if (ExtendedFormat == BIGFIRST)
RomHeader += 0x400000;
if (HiROM)
RomHeader += 0x8000;
S9xInitBSX(); // Set BS header before parsing
ParseSNESHeader(RomHeader);
//// Detect and initialize chips
//// detection codes are compatible with NSRT
// DSP1/2/3/4
if (ROMType == 0x03)
{
if (ROMSpeed == 0x30)
Settings.DSP = 4; // DSP4
else
Settings.DSP = 1; // DSP1
}
else
if (ROMType == 0x05)
{
if (ROMSpeed == 0x20)
Settings.DSP = 2; // DSP2
else
if (ROMSpeed == 0x30 && RomHeader[0x2a] == 0xb2)
Settings.DSP = 3; // DSP3
else
Settings.DSP = 1; // DSP1
}
switch (Settings.DSP)
{
case 1: // DSP1
if (HiROM)
{
DSP0.boundary = 0x7000;
DSP0.maptype = M_DSP1_HIROM;
}
else
if (CalculatedSize > 0x100000)
{
DSP0.boundary = 0x4000;
DSP0.maptype = M_DSP1_LOROM_L;
}
else
{
DSP0.boundary = 0xc000;
DSP0.maptype = M_DSP1_LOROM_S;
}
SetDSP = &DSP1SetByte;
GetDSP = &DSP1GetByte;
break;
case 2: // DSP2
DSP0.boundary = 0x10000;
DSP0.maptype = M_DSP2_LOROM;
SetDSP = &DSP2SetByte;
GetDSP = &DSP2GetByte;
break;
case 3: // DSP3
DSP0.boundary = 0xc000;
DSP0.maptype = M_DSP3_LOROM;
SetDSP = &DSP3SetByte;
GetDSP = &DSP3GetByte;
break;
case 4: // DSP4
DSP0.boundary = 0xc000;
DSP0.maptype = M_DSP4_LOROM;
SetDSP = &DSP4SetByte;
GetDSP = &DSP4GetByte;
break;
default:
SetDSP = NULL;
GetDSP = NULL;
break;
}
uint32 identifier = ((ROMType & 0xff) << 8) + (ROMSpeed & 0xff);
switch (identifier)
{
// SRTC
case 0x5535:
Settings.SRTC = TRUE;
S9xInitSRTC();
break;
// SPC7110
case 0xF93A:
Settings.SPC7110RTC = TRUE;
case 0xF53A:
Settings.SPC7110 = TRUE;
S9xInitSPC7110();
break;
// OBC1
case 0x2530:
Settings.OBC1 = TRUE;
break;
// SA1
case 0x3423:
case 0x3523:
Settings.SA1 = TRUE;
break;
// SuperFX
case 0x1320:
case 0x1420:
case 0x1520:
case 0x1A20:
Settings.SuperFX = TRUE;
S9xInitSuperFX();
if (ROM[0x7FDA] == 0x33)
SRAMSize = ROM[0x7FBD];
else
SRAMSize = 5;
break;
// SDD1
case 0x4332:
case 0x4532:
Settings.SDD1 = TRUE;
break;
// ST018
case 0xF530:
Settings.SETA = ST_018;
SetSETA = NULL;
GetSETA = NULL;
SRAMSize = 2;
SNESGameFixes.SRAMInitialValue = 0x00;
break;
// ST010/011
case 0xF630:
if (ROM[0x7FD7] == 0x09)
{
Settings.SETA = ST_011;
SetSETA = &S9xSetST011;
GetSETA = &S9xGetST011;
}
else
{
Settings.SETA = ST_010;
SetSETA = &S9xSetST010;
GetSETA = &S9xGetST010;
}
SRAMSize = 2;
SNESGameFixes.SRAMInitialValue = 0x00;
break;
// C4
case 0xF320:
Settings.C4 = TRUE;
break;
}
// MSU1
Settings.MSU1 = MsuRomExists();
//// Map memory and calculate checksum
Map_Initialize();
CalculatedChecksum = 0;
// SRAM size
SRAMMask = SRAMSize ? ((1 << (SRAMSize + 3)) * 128) - 1 : 0;
if (HiROM)
{
if (Settings.BS)
/* Do nothing */;
else
if (Settings.SPC7110)
Map_SPC7110HiROMMap();
else
if (ExtendedFormat != NOPE)
Map_ExtendedHiROMMap();
else
if (Multi.cartType == 3)
Map_SameGameHiROMMap();
else
Map_HiROMMap();
}
else
{
if (Settings.BS)
/* Do nothing */;
else
if (Settings.SETA && Settings.SETA != ST_018)
Map_SetaDSPLoROMMap();
else
if (Settings.SuperFX)
Map_SuperFXLoROMMap();
else
if (Settings.SA1)
{
if (Multi.cartType == 5)
Map_GNEXTSA1LoROMMap();
else
Map_SA1LoROMMap();
}
else
if (Settings.SDD1)
Map_SDD1LoROMMap();
else
if (ExtendedFormat != NOPE)
Map_JumboLoROMMap();
else
if (strncmp(ROMName, "WANDERERS FROM YS", 17) == 0)
Map_NoMAD1LoROMMap();
else
if (strncmp(ROMName, "SOUND NOVEL-TCOOL", 17) == 0 ||
strncmp(ROMName, "DERBY STALLION 96", 17) == 0)
Map_ROM24MBSLoROMMap();
else
if (strncmp(ROMName, "THOROUGHBRED BREEDER3", 21) == 0 ||
strncmp(ROMName, "RPG-TCOOL 2", 11) == 0)
Map_SRAM512KLoROMMap();
else
if (strncmp(ROMName, "ADD-ON BASE CASSETE", 19) == 0)
{
if (Multi.cartType == 4)
{
SRAMSize = Multi.sramSizeA;
Map_SufamiTurboLoROMMap();
}
else
{
SRAMSize = 5;
Map_SufamiTurboPseudoLoROMMap();
}
}
else
Map_LoROMMap();
}
Checksum_Calculate();
bool8 isChecksumOK = (ROMChecksum + ROMComplementChecksum == 0xffff) &
(ROMChecksum == CalculatedChecksum);
//// Build more ROM information
// CRC32
if (!Settings.BS || Settings.BSXItself) // Not BS Dump
ROMCRC32 = caCRC32(ROM, CalculatedSize);
else // Convert to correct format before scan
{
int offset = HiROM ? 0xffc0 : 0x7fc0;
// Backup
uint8 BSMagic0 = ROM[offset + 22],
BSMagic1 = ROM[offset + 23];
// uCONSRT standard
ROM[offset + 22] = 0x42;
ROM[offset + 23] = 0x00;
// Calc
ROMCRC32 = caCRC32(ROM, CalculatedSize);
// Convert back
ROM[offset + 22] = BSMagic0;
ROM[offset + 23] = BSMagic1;
}
// NTSC/PAL
if (Settings.ForceNTSC)
Settings.PAL = FALSE;
else
if (Settings.ForcePAL)
Settings.PAL = TRUE;
else
if (!Settings.BS && (ROMRegion >= 2) && (ROMRegion <= 12))
Settings.PAL = TRUE;
else
Settings.PAL = FALSE;
if (Settings.PAL)
{
Settings.FrameTime = Settings.FrameTimePAL;
ROMFramesPerSecond = 50;
}
else
{
Settings.FrameTime = Settings.FrameTimeNTSC;
ROMFramesPerSecond = 60;
}
// truncate cart name
ROMName[ROM_NAME_LEN - 1] = 0;
if (strlen(ROMName))
{
char *p = ROMName + strlen(ROMName);
if (p > ROMName + 21 && ROMName[20] == ' ')
p = ROMName + 21;
while (p > ROMName && *(p - 1) == ' ')
p--;
*p = 0;
}
// checksum
if (!isChecksumOK || ((uint32) CalculatedSize > (uint32) (((1 << (ROMSize - 7)) * 128) * 1024)))
{
Settings.DisplayColor = BUILD_PIXEL(31, 31, 0);
SET_UI_COLOR(255, 255, 0);
}
if (Multi.cartType == 4)
{
Settings.DisplayColor = BUILD_PIXEL(0, 16, 31);
SET_UI_COLOR(0, 128, 255);
}
//// Initialize emulation
Timings.H_Max_Master = SNES_CYCLES_PER_SCANLINE;
Timings.H_Max = Timings.H_Max_Master;
Timings.HBlankStart = SNES_HBLANK_START_HC;
Timings.HBlankEnd = SNES_HBLANK_END_HC;
Timings.HDMAInit = SNES_HDMA_INIT_HC;
Timings.HDMAStart = SNES_HDMA_START_HC;
Timings.RenderPos = SNES_RENDER_START_HC;
Timings.V_Max_Master = Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER;
Timings.V_Max = Timings.V_Max_Master;
/* From byuu: The total delay time for both the initial (H)DMA sync (to the DMA clock),
and the end (H)DMA sync (back to the last CPU cycle's mcycle rate (6, 8, or 12)) always takes between 12-24 mcycles.
Possible delays: { 12, 14, 16, 18, 20, 22, 24 }
XXX: Snes9x can't emulate this timing :( so let's use the average value... */
Timings.DMACPUSync = 18;
/* If the CPU is halted (i.e. for DMA) while /NMI goes low, the NMI will trigger
after the DMA completes (even if /NMI goes high again before the DMA
completes). In this case, there is a 24-30 cycle delay between the end of DMA
and the NMI handler, time enough for an instruction or two. */
// Wild Guns, Mighty Morphin Power Rangers - The Fighting Edition
Timings.NMIDMADelay = 24;
Timings.IRQPendCount = 0;
IPPU.TotalEmulatedFrames = 0;
//// Hack games
ApplyROMFixes();
//// Show ROM information
char displayName[ROM_NAME_LEN];
strcpy(RawROMName, ROMName);
sprintf(displayName, "%s", SafeANK(ROMName));
sprintf(ROMName, "%s", Safe(ROMName));
sprintf(ROMId, "%s", Safe(ROMId));
sprintf(String, "\"%s\" [%s] %s, %s, %s, %s, SRAM:%s, ID:%s, CRC32:%08X",
displayName, isChecksumOK ? "checksum ok" : ((Multi.cartType == 4) ? "no checksum" : "bad checksum"),
MapType(), Size(), KartContents(), Settings.PAL ? "PAL" : "NTSC", StaticRAMSize(), ROMId, ROMCRC32);
S9xMessage(S9X_INFO, S9X_ROM_INFO, String);
Settings.ForceLoROM = FALSE;
Settings.ForceHiROM = FALSE;
Settings.ForceHeader = FALSE;
Settings.ForceNoHeader = FALSE;
Settings.ForceInterleaved = FALSE;
Settings.ForceInterleaved2 = FALSE;
Settings.ForceInterleaveGD24 = FALSE;
Settings.ForceNotInterleaved = FALSE;
Settings.ForcePAL = FALSE;
Settings.ForceNTSC = FALSE;
if (PostRomInitFunc)
PostRomInitFunc();
S9xVerifyControllers();
}