Skip to content
Permalink
mecm
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
/*
* Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
*
* (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
* Jerremy Koot (jkoot@snes9x.com)
*
* Super FX C emulator code
* (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
* Gary Henderson.
* Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
*
* DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
* C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
* C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com).
*
* DOS port code contains the works of other authors. See headers in
* individual files.
*
* Snes9x homepage: http://www.snes9x.com
*
* Permission to use, copy, modify and distribute Snes9x in both binary and
* source form, for non-commercial purposes, is hereby granted without fee,
* providing that this license information and copyright notice appear with
* all copies and any derived work.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event shall the authors be held liable for any damages
* arising from the use of this software.
*
* Snes9x is freeware for PERSONAL USE only. Commercial users should
* seek permission of the copyright holders first. Commercial use includes
* charging money for Snes9x or software derived from Snes9x.
*
* The copyright holders request that bug fixes and improvements to the code
* should be forwarded to them so everyone can benefit from the modifications
* in future versions.
*
* Super NES and Super Nintendo Entertainment System are trademarks of
* Nintendo Co., Limited and its subsidiary companies.
*/
#ifndef __GP32__
//#include <string.h>
//#include <ctype.h>
#endif
extern const char *S9xGetSaveFilename( const char *e );
#ifdef __linux
#include <unistd.h>
#endif
#include "snes9x.h"
#include "memmap.h"
#include "cpuexec.h"
#include "ppu.h"
#include "display.h"
extern "C" {
#ifdef __psp__
#include <kubridge.h>
#endif
#include "cheats.h"
}
#include "apu.h"
#include "sa1.h"
#include "srtc.h"
#include "sdd1.h"
#include "spc7110.h"
#include "soundux.h"
#ifdef UNZIP_SUPPORT
#include "unzip.h"
#endif
#ifndef ZSNES_FX
#include "fxemu.h"
extern struct FxInit_s SuperFX;
#else
START_EXTERN_C
extern uint8 *SFXPlotTable;
END_EXTERN_C
#endif
static uint8 bytes0x2000 [0x2000];
extern uint8*sdd1_buffer;
/*extern int *Echo;// [32768];
extern int *DummyEchoBuffer;// [SOUND_BUFFER_SIZE];
extern int *MixBuffer;// [SOUND_BUFFER_SIZE];
extern int *EchoBuffer;*/
//add azz 080517
#include "bsx.h"
extern "C" {
uint32 caCRC32(uint8 *array, uint32 size, register uint32 crc32 = 0xFFFFFFFF);
}
bool8 CMemory::AllASCII (uint8 *b, int size)
{
for (int i = 0; i < size; i++)
{
if (b[i] < 32 || b[i] > 126)
return (FALSE);
}
return (TRUE);
}
int CMemory::ScoreHiROM (bool8 skip_header)
{
int score = 0;
int o = skip_header ? 0xff00 + 0x200 : 0xff00;
if(ROM [o + 0xd5] & 0x1)
score+=2;
//Mode23 is SA-1
if(ROM [o + 0xd5] == 0x23)
score-=2;
if(ROM [o+0xd4] == 0x20)
score +=2;
if ((ROM [o + 0xdc] + (ROM [o + 0xdd] << 8) +
ROM [o + 0xde] + (ROM [o + 0xdf] << 8)) == 0xffff)
{
score += 2;
if(0!=(ROM [o + 0xde] + (ROM [o + 0xdf] << 8)))
score++;
}
if (ROM [o + 0xda] == 0x33)
score += 2;
if ((ROM [o + 0xd5] & 0xf) < 4)
score += 2;
if (!(ROM [o + 0xfd] & 0x80))
score -= 6;
if ((ROM [o + 0xfc]|(ROM [o + 0xfd]<<8))>0xFFB0)
score -= 2; //reduced after looking at a scan by Cowering
if (CalculatedSize > 1024 * 1024 * 3)
score += 4;
if ((1 << (ROM [o + 0xd7] - 7)) > 48)
score -= 1;
if (!AllASCII (&ROM [o + 0xb0], 6))
score -= 1;
if (!AllASCII (&ROM [o + 0xc0], ROM_NAME_LEN - 1))
score -= 1;
return (score);
}
int CMemory::ScoreLoROM (bool8 skip_header)
{
int score = 0;
int o = skip_header ? 0x7f00 + 0x200 : 0x7f00;
if(!(ROM [o + 0xd5] & 0x1))
score+=3;
//Mode23 is SA-1
if(ROM [o + 0xd5] == 0x23)
score+=2;
if ((ROM [o + 0xdc] + (ROM [o + 0xdd] << 8) +
ROM [o + 0xde] + (ROM [o + 0xdf] << 8)) == 0xffff)
{
score += 2;
if(0!=(ROM [o + 0xde] + (ROM [o + 0xdf] << 8)))
score++;
}
if (ROM [o + 0xda] == 0x33)
score += 2;
if ((ROM [o + 0xd5] & 0xf) < 4)
score += 2;
if (CalculatedSize <= 1024 * 1024 * 16)
score += 2;
if (!(ROM [o + 0xfd] & 0x80))
score -= 6;
if ((ROM [o + 0xfc]|(ROM [o + 0xfd]<<8))>0xFFB0)
score -= 2;//reduced per Cowering suggestion
if ((1 << (ROM [o + 0xd7] - 7)) > 48)
score -= 1;
if (!AllASCII (&ROM [o + 0xb0], 6))
score -= 1;
if (!AllASCII (&ROM [o + 0xc0], ROM_NAME_LEN - 1))
score -= 1;
return (score);
}
/*char *CMemory::Safe (const char *s)
{
static char *safe = NULL;
static int safe_len = 0;
int len = strlen (s);
if (!safe || len + 1 > safe_len)
{
if (safe)
free ((char *) safe);
safe = (char *) malloc (safe_len = len + 1);
}
for (int i = 0; i < len; i++)
{
if (s [i] >= 32 && s [i] < 127)
safe [i] = s[i];
else
safe [i] = '?';
}
safe [len] = 0;
return (safe);
}*/
/**********************************************************************************************/
/* Init() */
/* This function allocates all the memory needed by the emulator */
/**********************************************************************************************/
//extern unsigned int __attribute__((aligned(16))) clut256[256*3];
extern u16 *clut256;
extern u8 *tile_texture[3];
bool8 CMemory::Init ()
{
//DEBUGS("9a");
//RAM = (uint8 *) malloc (0x20000);
//DEBUGS("9b");
// SRAM = (uint8 *) malloc (0x20000+MAX_RTC_INDEX+16);
// VRAM = (uint8 *) malloc (0x10000);
//DEBUGS("9c");
//ROM_GLOBAL = (uint8 *) malloc(0x8000);
C4RAM = (uint8 *) malloc(0x2000);
sdd1_buffer = (uint8 *) malloc (0x10000);
//DEBUGS("9d");
//try to use storage instead of heap mem
#ifdef __psp__
if(kuKernelGetModel() > 0) {
MAX_ROM_SIZE = 0x1000000;
//ROM_HANDLER = sceKernelAllocPartitionMemory(
// sceKernelDevkitVersion() >> 24 == 6 ? 9 : 8, "ROM", PSP_SMEM_Low, MAX_ROM_SIZE + 0x200 + 0x8000, NULL);
//ROM_GLOBAL = (uint8 *)(ROM_HANDLER <= 0 ? 0 : sceKernelGetBlockHeadAddr(ROM_HANDLER));
ROM_GLOBAL = (uint8 *)0xA000000;
} else
#endif
{
MAX_ROM_SIZE = 0x600000;
ROM_GLOBAL = (uint8 *)malloc(MAX_ROM_SIZE + 0x200 + 0x8000);
}
memset(ROM_GLOBAL, 0, MAX_ROM_SIZE + 0x200 + 0x8000);
ROM = ROM_GLOBAL + 0x8000;
#ifdef _BSX_151_
BSRAM = ROM + 0x400000;
BIOSROM = ROM + 0x300000;
#endif
//DEBUGS("9e");
//ROM_GLOBAL = NULL;
clut256=(u16*)(0x44000000+2*512*272*2+256*240*2+3*256*256*2);
tile_texture[0]=(u8*)(0x44000000+2*512*272*2+256*240*2+3*256*256*2+256*2*3);
tile_texture[1]=tile_texture[0]+512*512;
tile_texture[2]=tile_texture[1]+512*512; //here we're very close to the 2MB limit...
// VRAMmode7=tile_texture[2]+512*512;
IPPU.TileCache [TILE_2BIT] = (uint8 *) malloc (MAX_2BIT_TILES * (128+8));
IPPU.TileCache [TILE_4BIT] = (uint8 *) malloc (MAX_4BIT_TILES * (128+8));
IPPU.TileCache [TILE_8BIT] = (uint8 *) malloc (MAX_8BIT_TILES * (128+8));
IPPU.TileCache8 [TILE_2BIT] = (uint8 *) malloc (MAX_2BIT_TILES * (64));
IPPU.TileCache8 [TILE_4BIT] = (uint8 *) malloc (MAX_4BIT_TILES * (64));
IPPU.TileCache8 [TILE_8BIT] = (uint8 *) malloc (MAX_8BIT_TILES * (64));
IPPU.TileCached [TILE_2BIT] = (uint8 *) malloc ((MAX_2BIT_TILES+MAX_4BIT_TILES+MAX_8BIT_TILES) * 2);
IPPU.TileCached [TILE_4BIT] = IPPU.TileCached [TILE_2BIT]+MAX_2BIT_TILES * 2;
IPPU.TileCached [TILE_8BIT] = IPPU.TileCached [TILE_4BIT]+MAX_4BIT_TILES * 2;
// DEBUGS("9f");
if (/*!Echo||!DummyEchoBuffer||!MixBuffer||!EchoBuffer||*/!sdd1_buffer || !C4RAM || /*!ROM_GLOBAL || !RAM || !SRAM || !VRAM ||*/ !ROM ||
!IPPU.TileCache [TILE_2BIT] || !IPPU.TileCache [TILE_4BIT] ||
!IPPU.TileCache [TILE_8BIT] || !IPPU.TileCached [TILE_2BIT] ||
!IPPU.TileCached [TILE_4BIT] || !IPPU.TileCached [TILE_8BIT])
{
#ifdef __psp__
msgBoxLines(s9xTYL_msg[ERR_CANNOT_ALLOC_MEM], 30);
pgwaitPress();
#else
S9xMessage(-1,0,"Cannot allocate memory");
#endif
Deinit ();
return (FALSE);
}
// ROM_GLOBAL uses first 32K of ROM image area, otherwise space just
// wasted. Might be read by the SuperFX code.
// ROM_GLOBAL = ROM;
// Add 0x8000 to ROM image pointer to stop SuperFX code accessing
// unallocated memory (can cause crash on some ports).
// ROM += 0x8000;
//C4RAM = ROM + 0x400000 + 8192 * 8;
// ::ROM = ROM;
// ::SRAM = SRAM;
// ::RegRAM = ROM_GLOBAL;
#ifdef ZSNES_FX
SFXPlotTable = ROM + 0x400000;
#else
SuperFX.pvRegisters = &ROM_GLOBAL [0x3000];
SuperFX.nRamBanks = 2; // Most only use 1. 1=64KB, 2=128KB=1024Mb
SuperFX.pvRam = ::SRAM;
SuperFX.nRomBanks = (2 * 1024 * 1024) / (32 * 1024);
SuperFX.pvRom = (uint8 *) ROM;
#endif
ZeroMemory (IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES);
ZeroMemory (IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES);
ZeroMemory (IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES);
tile_askforreset(-1);
SDD1Data = NULL;
SDD1Index = NULL;
return (TRUE);
}
void CMemory::Deinit ()
{
if (sdd1_buffer){free(sdd1_buffer);sdd1_buffer=NULL;}
/* if (RAM)
{free ((uint8*)RAM);RAM = NULL;} */
if (ROM_GLOBAL) {
#ifdef __psp__
if(kuKernelGetModel() > 0)
{ROM_GLOBAL = ROM = NULL;}
else
#endif
{free(ROM_GLOBAL);ROM_GLOBAL = ROM = NULL;}
}
//if (ROM_GLOBAL)
//{free((uint8*)ROM_GLOBAL);ROM_GLOBAL = NULL;}
if (C4RAM)
{free((uint8*)C4RAM);C4RAM = NULL;}
if (IPPU.TileCache [TILE_2BIT])
{free ((char *) IPPU.TileCache [TILE_2BIT]);IPPU.TileCache [TILE_2BIT] = NULL;}
if (IPPU.TileCache [TILE_4BIT])
{free ((char *) IPPU.TileCache [TILE_4BIT]);IPPU.TileCache [TILE_4BIT] = NULL;}
if (IPPU.TileCache [TILE_8BIT])
{free ((char *) IPPU.TileCache [TILE_8BIT]);IPPU.TileCache [TILE_8BIT] = NULL;}
if (IPPU.TileCache8 [TILE_2BIT])
{free ((char *) IPPU.TileCache8 [TILE_2BIT]);IPPU.TileCache8 [TILE_2BIT] = NULL;}
if (IPPU.TileCache8 [TILE_4BIT])
{free ((char *) IPPU.TileCache8 [TILE_4BIT]);IPPU.TileCache8 [TILE_4BIT] = NULL;}
if (IPPU.TileCache8 [TILE_8BIT])
{free ((char *) IPPU.TileCache8 [TILE_8BIT]);IPPU.TileCache8 [TILE_8BIT] = NULL;}
if (IPPU.TileCached [TILE_2BIT])
{free ((char *) IPPU.TileCached [TILE_2BIT]);IPPU.TileCached [TILE_2BIT] = NULL;}
/* if (IPPU.TileCached [TILE_4BIT])
{
free ((char *) IPPU.TileCached [TILE_4BIT]);
IPPU.TileCached [TILE_4BIT] = NULL;
}
if (IPPU.TileCached [TILE_8BIT])
{
free ((char *) IPPU.TileCached [TILE_8BIT]);
IPPU.TileCached [TILE_8BIT] = NULL;
}*/
FreeSDD1Data ();
}
void CMemory::FreeSDD1Data ()
{
if (SDD1Index)
{
free ((char *) SDD1Index);
SDD1Index = NULL;
}
if (SDD1Data)
{
free ((char *) SDD1Data);
SDD1Data = NULL;
}
}
void CMemory::DeInterleavedRom(bool8 Tales)
{
int i;
CPU.TriedInterleavedMode2 = TRUE;
int nblocks = CalculatedSize >> 16;
int blocks [256];
if (Tales)
{
nblocks = 0x60;
for (i = 0; i < 0x40; i += 2)
{
blocks [i + 0] = (i >> 1) + 0x20;
blocks [i + 1] = (i >> 1) + 0x00;
}
for (i = 0; i < 0x80; i += 2)
{
blocks [i + 0x40] = (i >> 1) + 0x80;
blocks [i + 0x41] = (i >> 1) + 0x40;
}
LoROM = FALSE;
HiROM = TRUE;
}
else
if (Settings.ForceInterleaved2)
{
for (i = 0; i < nblocks * 2; i++)
{
blocks [i] = (i & (0xff^0x1e)) | ((i & 2) << 2) | ((i & 4) << 2) |
((i & 8) >> 2) | ((i & 16) >> 2);
}
}
else
{
bool8 t = LoROM;
LoROM = HiROM;
HiROM = t;
for (i = 0; i < nblocks; i++)
{
blocks [i * 2] = i + nblocks;
blocks [i * 2 + 1] = i;
}
}
uint8 *tmp = (uint8 *) malloc (0x8000);
if (tmp)
{
S9xMessage(0,0,"DeInterleaving");
for (i = 0; i < nblocks * 2; i++)
{
for (int j = i; j < nblocks * 2; j++)
{
if (blocks [j] == i)
{
if (blocks[j]!=blocks[i])
{
memcpy (tmp, ROM + blocks [j] * 0x8000UL, 0x8000);
memcpy (ROM+ blocks [j] * 0x8000UL,ROM + blocks [i] * 0x8000UL, 0x8000);
memcpy(ROM+ blocks [i] * 0x8000UL, tmp, 0x8000);
}
uint8 b = blocks [j];
blocks [j] = blocks [i];
blocks [i] = b;
break;
}
}
}
free ((char *) tmp);
}
}
void FixMapPSP()
{
return;
for(int i=0;i<MEMMAP_NUM_BLOCKS;i++)
{
if(Map [i]>=(uint8 *)CMemory::MAP_LAST && Memory.BlockIsRAM[i] == TRUE)
Map [i] = (uint8*)((uint) (Map[i])|0x80000000);
}
}
int CMemory::LoadROMMore(int TotalFileSize,int &retry_count)
{
bool8 Interleaved = FALSE;
bool8 Tales = FALSE;
int hi_score = ScoreHiROM (FALSE);
int lo_score = ScoreLoROM (FALSE);
if (HeaderCount == 0 && !Settings.ForceNoHeader &&
((hi_score > lo_score && ScoreHiROM (TRUE) > hi_score) ||
(hi_score <= lo_score && ScoreLoROM (TRUE) > lo_score)))
{
memmove (ROM, ROM + 512, TotalFileSize - 512);
TotalFileSize -= 512;
//S9xMessage (S9X_INFO, S9X_HEADER_WARNING,
// "Try specifying the -nhd command line option if the game doesn't work\n");
}
CalculatedSize = (TotalFileSize / 0x2000) * 0x2000;
ZeroMemory (ROM + CalculatedSize, MAX_ROM_SIZE - CalculatedSize);
// Check for cherryroms.com DAIKAIJYUMONOGATARI2
if (CalculatedSize == 0x500000 &&
strncmp ((const char *)&ROM [0x40ffc0], "DAIKAIJYUMONOGATARI2", 20) == 0 &&
strncmp ((const char *)&ROM [0x40ffb0], "18AE6J", 6) == 0 &&
memcmp (&ROM[0x40ffb0], &ROM [0xffb0], 0x30))
{
//Change
memmove (&ROM[0x100000], ROM, 0x500000);
memmove (ROM, &ROM[0x500000], 0x100000);
}
Interleaved = Settings.ForceInterleaved || Settings.ForceInterleaved2;
if (Settings.ForceLoROM || (!Settings.ForceHiROM && lo_score >= hi_score))
{
LoROM = TRUE;
HiROM = FALSE;
// Ignore map type byte if not 0x2x or 0x3x
if ((ROM [0x7fd5] & 0xf0) == 0x20 || (ROM [0x7fd5] & 0xf0) == 0x30)
{
switch (ROM [0x7fd5] & 0xf)
{
case 1:
if (strncmp ((char *) &ROM [0x7fc0], "TREASURE HUNTER G", 17) != 0)
Interleaved = TRUE;
break;
case 2:
#if 0
if (!Settings.ForceLoROM &&
strncmp ((char *) &ROM [0x7fc0], "SUPER FORMATION SOCCE", 21) != 0 &&
strncmp ((char *) &ROM [0x7fc0], "Star Ocean", 10) != 0)
{
LoROM = FALSE;
HiROM = TRUE;
}
#endif
break;
case 5:
Interleaved = TRUE;
Tales = TRUE;
break;
}
}
}
else
{
if ((ROM [0xffd5] & 0xf0) == 0x20 || (ROM [0xffd5] & 0xf0) == 0x30)
{
switch (ROM [0xffd5] & 0xf)
{
case 0:
case 3:
Interleaved = TRUE;
break;
}
}
LoROM = FALSE;
HiROM = TRUE;
}
if (!Settings.ForceHiROM && !Settings.ForceLoROM &&
!Settings.ForceInterleaved && !Settings.ForceInterleaved2 &&
!Settings.ForceNotInterleaved && !Settings.ForcePAL &&
!Settings.ForceSuperFX && !Settings.ForceDSP1 &&
!Settings.ForceSA1 && !Settings.ForceC4 &&
!Settings.ForceSDD1)
{
if(strncmp((char *) &ROM [0x7fc0], "YOSHI'S ISLAND", 14) == 0&&(*(uint16*)&ROM[0x7FDE])==57611&&ROM[0x10002]==0xA9)
{
Interleaved=true;
Settings.ForceInterleaved2=true;
}
if (strncmp ((char *) &ROM [0x7fc0], "YUYU NO QUIZ DE GO!GO!", 22) == 0)
{
LoROM = TRUE;
HiROM = FALSE;
Interleaved = FALSE;
}
else
if (strncmp ((char *) &ROM [0x7fc0], "SP MOMOTAROU DENTETSU2", 22) == 0)
{
LoROM = TRUE;
HiROM = FALSE;
Interleaved = FALSE;
}
else
if (CalculatedSize == 0x100000 &&
strncmp ((char *) &ROM [0xffc0], "WWF SUPER WRESTLEMANIA", 22) == 0)
{
int cvcount;
memmove (&ROM[0x100000] , ROM, 0x100000);
for (cvcount = 0; cvcount < 16; cvcount++)
{
memmove (&ROM[0x8000 * cvcount], &ROM[0x10000 * cvcount + 0x100000 + 0x8000], 0x8000);
memmove (&ROM[0x8000 * cvcount + 0x80000], &ROM[0x10000 * cvcount + 0x100000], 0x8000);
}
LoROM = TRUE;
HiROM = FALSE;
ZeroMemory (ROM + CalculatedSize, MAX_ROM_SIZE - CalculatedSize);
}
}
if (!Settings.ForceNotInterleaved && Interleaved)
{
S9xMessage(0,0,"interleaved ROM");
DeInterleavedRom(Tales);
#ifdef __psp__
msgBoxLines(s9xTYL_msg[CONV_DONE], 30);
#else
S9xMessage(0,0,"conversion done");
#endif
hi_score = ScoreHiROM (FALSE);
lo_score = ScoreLoROM (FALSE);
if ((HiROM &&
(lo_score >= hi_score || hi_score < 0)) ||
(LoROM &&
(hi_score > lo_score || lo_score < 0)))
{
if (retry_count == 0)
{
#ifdef __psp__
msgBoxLines(s9xTYL_msg[ROM_LIED], 30);
#else
S9xMessage(0,0,"ROM lied about its type! Trying again.");
#endif
Settings.ForceNotInterleaved = TRUE;
Settings.ForceInterleaved = FALSE;
retry_count++;
//goto again;
return 1;
}
}
}
FreeSDD1Data ();
InitROM (Tales);
return 0;
}
#ifdef _BSX_151_
int CMemory::LoadROMMore_151(int TotalFileSize,int &retry_count)
{
bool8 Interleaved = FALSE;
bool8 Tales = FALSE;
int orig_hi_score, orig_lo_score;
int hi_score, lo_score;
int i;
orig_hi_score = hi_score = ScoreHiROM (FALSE);
orig_lo_score = lo_score = ScoreLoROM (FALSE);
if (HeaderCount == 0 && !Settings.ForceNoHeader &&
((hi_score > lo_score && ScoreHiROM (TRUE) > hi_score) ||
(hi_score <= lo_score && ScoreLoROM (TRUE) > lo_score)))
{
memmove (ROM, ROM + 512, TotalFileSize - 512);
TotalFileSize -= 512;
//S9xMessage (S9X_INFO, S9X_HEADER_WARNING,
// "Try specifying the -nhd command line option if the game doesn't work\n");
}
CalculatedSize = (TotalFileSize / 0x2000) * 0x2000;
ZeroMemory (ROM + CalculatedSize, MAX_ROM_SIZE - CalculatedSize);
ExtendedFormat = NOPE;
// Check for cherryroms.com DAIKAIJYUMONOGATARI2
if (CalculatedSize == 0x500000 &&
strncmp ((const char *)&ROM [0x40ffc0], "DAIKAIJYUMONOGATARI2", 20) == 0 &&
strncmp ((const char *)&ROM [0x40ffb0], "18AE6J", 6) == 0 &&
memcmp (&ROM[0x40ffb0], &ROM [0xffb0], 0x30))
{
//Change
memmove (&ROM[0x100000], ROM, 0x500000);
memmove (ROM, &ROM[0x500000], 0x100000);
}
//151
if (CalculatedSize > 0x400000 &&
(ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x4332 && // exclude S-DD1
(ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x4532 &&
(ROM[0xffd5] + (ROM[0xffd6] << 8)) != 0xF93a && // exclude SPC7110
(ROM[0xffd5] + (ROM[0xffd6] << 8)) != 0xF53a)
ExtendedFormat = YEAH;
if (ExtendedFormat != NOPE)
{
//int swappedhirom, swappedlorom;
//swappedhirom = ScoreHiROM(FALSE, 0x400000);
//swappedlorom = ScoreLoROM(FALSE, 0x400000);
//// set swapped here
//if (max(swappedlorom, swappedhirom) >= max(lo_score, hi_score))
//{
// ExtendedFormat = BIGFIRST;
// hi_score = swappedhirom;
// lo_score = swappedlorom;
// RomHeader += 0x400000;
//}
//else
ExtendedFormat = SMALLFIRST;
}
Interleaved = Settings.ForceInterleaved || Settings.ForceInterleaved2;
if (Settings.ForceLoROM || (!Settings.ForceHiROM && lo_score >= hi_score))
{
LoROM = TRUE;
HiROM = FALSE;
// Ignore map type byte if not 0x2x or 0x3x
if ((ROM [0x7fd5] & 0xf0) == 0x20 || (ROM [0x7fd5] & 0xf0) == 0x30)
{
switch (ROM [0x7fd5] & 0xf)
{
case 1:
if (strncmp ((char *) &ROM [0x7fc0], "TREASURE HUNTER G", 17) != 0)
Interleaved = TRUE;
break;
case 2:
#if 0
if (!Settings.ForceLoROM &&
strncmp ((char *) &ROM [0x7fc0], "SUPER FORMATION SOCCE", 21) != 0 &&
strncmp ((char *) &ROM [0x7fc0], "Star Ocean", 10) != 0)
{
LoROM = FALSE;
HiROM = TRUE;
}
#endif
break;
case 5:
Interleaved = TRUE;
Tales = TRUE;
break;
}
}
}
else
{
if ((ROM [0xffd5] & 0xf0) == 0x20 || (ROM [0xffd5] & 0xf0) == 0x30)
{
switch (ROM [0xffd5] & 0xf)
{
case 0:
case 3:
Interleaved = TRUE;
break;
}
}
LoROM = FALSE;
HiROM = TRUE;
}
if (!Settings.ForceHiROM && !Settings.ForceLoROM &&
!Settings.ForceInterleaved && !Settings.ForceInterleaved2 &&
!Settings.ForceNotInterleaved && !Settings.ForcePAL &&
!Settings.ForceSuperFX && !Settings.ForceDSP1 &&
!Settings.ForceSA1 && !Settings.ForceC4 &&
!Settings.ForceSDD1)
{
if(strncmp((char *) &ROM [0x7fc0], "YOSHI'S ISLAND", 14) == 0&&(*(uint16*)&ROM[0x7FDE])==57611&&ROM[0x10002]==0xA9)
{
Interleaved=true;
Settings.ForceInterleaved2=true;
}
if (strncmp ((char *) &ROM [0x7fc0], "YUYU NO QUIZ DE GO!GO!", 22) == 0)
{
LoROM = TRUE;
HiROM = FALSE;
Interleaved = FALSE;
}
else
if (strncmp ((char *) &ROM [0x7fc0], "SP MOMOTAROU DENTETSU2", 22) == 0)
{
LoROM = TRUE;
HiROM = FALSE;
Interleaved = FALSE;
}
else
if (CalculatedSize == 0x100000 &&
strncmp ((char *) &ROM [0xffc0], "WWF SUPER WRESTLEMANIA", 22) == 0)
{
int cvcount;
memmove (&ROM[0x100000] , ROM, 0x100000);
for (cvcount = 0; cvcount < 16; cvcount++)
{
memmove (&ROM[0x8000 * cvcount], &ROM[0x10000 * cvcount + 0x100000 + 0x8000], 0x8000);
memmove (&ROM[0x8000 * cvcount + 0x80000], &ROM[0x10000 * cvcount + 0x100000], 0x8000);
}
LoROM = TRUE;
HiROM = FALSE;
ZeroMemory (ROM + CalculatedSize, MAX_ROM_SIZE - CalculatedSize);
}
}
if (!Settings.ForceNotInterleaved && Interleaved)
{
S9xMessage(0,0,"interleaved ROM");
DeInterleavedRom(Tales);
#ifdef __psp__
msgBoxLines(s9xTYL_msg[CONV_DONE], 30);
#else
S9xMessage(0,0,"conversion done");
#endif
hi_score = ScoreHiROM (FALSE);
lo_score = ScoreLoROM (FALSE);
if ((HiROM &&
(lo_score >= hi_score || hi_score < 0)) ||
(LoROM &&
(hi_score > lo_score || lo_score < 0)))
{
if (retry_count == 0)
{
#ifdef __psp__
msgBoxLines(s9xTYL_msg[ROM_LIED], 30);
#else
S9xMessage(0,0,"ROM lied about its type! Trying again.");
#endif
Settings.ForceNotInterleaved = TRUE;
Settings.ForceInterleaved = FALSE;
retry_count++;
//goto again;
return 1;
}
}
}
FreeSDD1Data ();
InitROM (Tales);
return 0;
}
#endif
/**********************************************************************************************/
/* LoadROM() */
/* This function loads a Snes-Backup image */
/**********************************************************************************************/
extern char rom_filename[256];
extern char shortrom_filename[64];
bool8 CMemory::LoadROM (const char *filename)
{
unsigned long FileSize = 0;
int retry_count = 0;
//STREAM ROMFile;
FILE *ROMFile;
int current_pos;
char ext [4 + 1];
char fname [256 + 1];
char name [256 + 1];
memset (&SNESGameFixes, 0, sizeof(SNESGameFixes));
SNESGameFixes.SRAMInitialValue = 0x60;
memset (bytes0x2000, 0, 0x2000);
CPU.TriedInterleavedMode2 = FALSE;
CalculatedSize = 0;
again:
// _splitpath (filename, drive, dir, name, ext);
// _makepath (fname, drive, dir, name, ext);
strcpy(name,shortrom_filename);
strcpy(fname,filename);
char *p = strrchr(rom_filename,'.');
if (p == NULL) return FALSE;
strcpy(ext, p + 1);
#if defined(__WIN32__)
memmove (&ext [0], &ext[1], 4);
#endif
uint32 TotalFileSize = 0;
#ifdef UNZIP_SUPPORT
if (strcasecmp (ext, "zip") == 0)
{
//S9xMessage(0,0,"File is zipped...\nSearching for a valide ROM inside");
//bool8 LoadZip (const char *, int32 *, int32 *);
//if (!LoadZip (fname, &TotalFileSize, &HeaderCount))
// return (FALSE);
unzFile zip_file = 0;
unz_file_info unzinfo;
char snes_file[256]; //yoyo
char *p;
uint8 *ptr=(uint8*)ROM;
// S9xMessage(1,0,"yo zip1");
zip_file = unzOpen(filename);
// S9xMessage(1,0,"yo zip2");
if (!zip_file) return FALSE;
// S9xMessage(1,0,"yo zip3");
unzGoToFirstFile (zip_file);
// S9xMessage(1,0,"yo zip4");
for (;;)
{
if (unzGetCurrentFileInfo(zip_file, &unzinfo, snes_file, sizeof(snes_file), NULL, 0, NULL, 0) != UNZ_OK) return FALSE;
p = (char*)(strrchr(snes_file, '.') + 1);
if (strcasecmp(p, "smc") == 0) break;
if (strcasecmp(p, "sfc") == 0) break;
if (strcasecmp(p, "swc") == 0) break;
if (strcasecmp(p, "bin") == 0) break;
if (strcasecmp(p, "fig") == 0) break;
// if (compare(p, ".1") == 0) break;
if (unzGoToNextFile(zip_file) != UNZ_OK) return FALSE;
}
// S9xMessage(1,0,"opening in zip file ,");
unzOpenCurrentFile (zip_file);
// S9xMessage(1,0,snes_file);
FileSize = unzinfo.uncompressed_size;
// char tmp[64];
// sprintf(tmp,"size : %d",FileSize);
// S9xMessage(1,0,tmp);
char str[64];
sprintf(str, s9xTYL_msg[LOADING_ROM], FileSize >> 10);
msgBoxLines(str, 0);
unzReadCurrentFile(zip_file,(void*)(ptr), FileSize, psp_showProgressBar);
// S9xMessage(1,0,"ok");
unzCloseCurrentFile (zip_file);
unzClose (zip_file);
int calc_size = (FileSize / 0x2000) * 0x2000;
if ((FileSize - calc_size == 512 && !Settings.ForceNoHeader) ||
Settings.ForceHeader)
{
memmove (ptr, ptr + 512, calc_size);
HeaderCount++;
FileSize -= 512;
}
TotalFileSize += FileSize;
strcpy (ROMFilename, fname);
}
else
#endif
{
//if ((ROMFile = OPEN_STREAM (fname, "rb")) == NULL)
//return (FALSE);
ROMFile = fopen(fname,"rb");
if (!ROMFile) return false;
strcpy (ROMFilename, fname);
HeaderCount = 0;
uint8 *ptr = ROM;
bool8 more = FALSE;
do
{
//FileSize = READ_STREAM (ptr, MAX_ROM_SIZE + 0x200 - (ptr - ROM), ROMFile);
fseek(ROMFile,0,SEEK_END);
FileSize=ftell(ROMFile);
fseek(ROMFile,0,SEEK_SET);
current_pos=FileSize;
char str[64];
sprintf(str, s9xTYL_msg[LOADING_ROM], FileSize >> 10);
msgBoxLines(str,0);
msgBoxLines(str,0); // this is to avoid flickering due to progressbar flipping the screen
while (current_pos>0) {
psp_showProgressBar(current_pos,FileSize);
if (current_pos>0x8000) {
fread(ptr,0x8000,1,ROMFile);
ptr+=0x8000;
current_pos-=0x8000;
} else {
fread(ptr,current_pos,1,ROMFile);
ptr+=current_pos;
current_pos=0;
}
}
psp_showProgressBar(FileSize-current_pos,FileSize);
ptr=ROM;
fclose(ROMFile);
//CLOSE_STREAM (ROMFile);
int calc_size = (FileSize / 0x2000) * 0x2000;
if ((FileSize - calc_size == 512 && !Settings.ForceNoHeader) || Settings.ForceHeader) {
memmove (ptr, ptr + 512, calc_size);
HeaderCount++;
FileSize -= 512;
}
TotalFileSize += FileSize;
int len;
if ((uint32)(ptr - ROM) < MAX_ROM_SIZE + 0x200 && (isdigit (ext [0]) && ext [1] == 0 && ext [0] < '9')) {
more = TRUE;
ext [0]++;
#if defined(__WIN32__)||defined(__GP32__)||defined(__psp__)
memmove (&ext [1], &ext [0], 4);
ext [0] = '.';
#endif
//_makepath (fname, drive, dir, name, ext);
}
else
if ((uint32)(ptr - ROM) < MAX_ROM_SIZE + 0x200 &&
(((len = strlen (name)) == 7 || len == 8) &&
strncasecmp (name, "sf", 2) == 0 &&
isdigit (name [2]) && isdigit (name [3]) && isdigit (name [4]) &&
isdigit (name [5]) && isalpha (name [len - 1])))
{
more = TRUE;
name [len - 1]++;
#if defined(__WIN32__)||defined(__GP32__)||defined(__psp__)
memmove (&ext [1], &ext [0], 4);
ext [0] = '.';
#endif
//_makepath (fname, drive, dir, name, ext);
}
else
{ more = FALSE; break;}
//} while (more && (ROMFile = OPEN_STREAM (fname, "rb")) != NULL);
} while (more && (ROMFile = fopen (fname, "rb")) != NULL);
}
/*if (HeaderCount == 0)
S9xMessage (S9X_INFO, S9X_HEADERS_INFO, "No ROM file header found.");
else
{
if (HeaderCount == 1)
S9xMessage (S9X_INFO, S9X_HEADERS_INFO,
"Found ROM file header (and ignored it).");
else
S9xMessage (S9X_INFO, S9X_HEADERS_INFO,
"Found multiple ROM file headers (and ignored them).");
}*/
CheckForIPSPatch (filename, HeaderCount != 0, TotalFileSize,".ips");
CheckForIPSPatch (filename, HeaderCount != 0, TotalFileSize,".ips1");
CheckForIPSPatch (filename, HeaderCount != 0, TotalFileSize,".ips2");
CheckForIPSPatch (filename, HeaderCount != 0, TotalFileSize,".ips3");
CheckForIPSPatch (filename, HeaderCount != 0, TotalFileSize,".ips4");
// More
#ifndef _BSX_151_
if (LoadROMMore(TotalFileSize,retry_count))
#else
if (LoadROMMore_151(TotalFileSize,retry_count))
#endif
{
goto again;
}
S9xLoadCheatFile (S9xGetSaveFilename(".cht"));
S9xInitCheatData ();
S9xApplyCheats ();
S9xReset ();
return (TRUE);
}
void S9xDeinterleaveMode2 ()
{
//S9xMessage (S9X_INFO, S9X_ROM_INTERLEAVED_INFO,
//"ROM image is in interleaved format - converting...");
S9xMessage(0,0,"deinterleaved mofe 2");
int nblocks = Memory.CalculatedSize >> 15;
int step = 64;
while (nblocks <= step)
step >>= 1;
nblocks = step;
uint8 blocks [256];
int i;
for (i = 0; i < nblocks * 2; i++)
{
blocks [i] = (i & ~0x1e) | ((i & 2) << 2) | ((i & 4) << 2) |
((i & 8) >> 2) | ((i & 16) >> 2);
}
uint8 *tmp = (uint8 *) malloc (0x8000);
if (tmp)
{
for (i = 0; i < nblocks * 2; i++)
{
for (int j = i; j < nblocks * 2; j++)
{
if (blocks [j] == i)
{
if (blocks[j]!=blocks[i])
{
memmove (tmp, &Memory.ROM [(uint32)(blocks [j]) * 0x8000], 0x8000);
memcpy(Memory.ROM+blocks [j] * 0x8000UL,Memory.ROM + blocks [i] * 0x8000UL, 0x8000);
memcpy(Memory.ROM+blocks [i] * 0x8000UL,tmp, 0x8000);
}
uint8 b = blocks [j];
blocks [j] = blocks [i];
blocks [i] = b;
break;
}
}
}
free ((char *) tmp);
}
Memory.InitROM (FALSE);
S9xReset ();
}
#ifdef _BSX_151_
void CMemory::ParseSNESHeader (uint8 *RomHeader)
{
bool8 bs = Settings.BS & !Settings.BSXItself;
strncpy(ROMName, (char *) &RomHeader[0x10], ROM_NAME_LEN - 1);
if (bs)
memset(ROMName + 16, 0x20, ROM_NAME_LEN - 17);
if (bs)
{
if (!(((RomHeader[0x29] & 0x20) && CalculatedSize < 0x100000) ||
(!(RomHeader[0x29] & 0x20) && CalculatedSize == 0x100000)))
printf("BS: Size mismatch\n");
// FIXME
int p = 0;
while ((1 << p) < (int) CalculatedSize)
p++;
ROMSize = p - 10;
}
else
ROMSize = RomHeader[0x27];
SRAMSize = bs ? 5 /* BS-X */ : RomHeader[0x28];
ROMSpeed = bs ? RomHeader[0x28] : RomHeader[0x25];
ROMType = bs ? 0xE5 /* BS-X */ : RomHeader[0x26];
// ROMRegion = bs ? 0 : RomHeader[0x29];//remove azz 080517
ROMChecksum = RomHeader[0x2E] + (RomHeader[0x2F] << 8);
ROMComplementChecksum = RomHeader[0x2C] + (RomHeader[0x2D] << 8);
memmove(ROMId, &RomHeader[0x02], 4);
if (RomHeader[0x2A] == 0x33)
memmove(CompanyId, &RomHeader[0x00], 2);
else
sprintf(CompanyId, "%02X", RomHeader[0x2A]);
}
void CMemory::BS_151()
{
CalculatedChecksum = 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)
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;
}
// SRAM size
SRAMMask = SRAMSize ? ((1 << (SRAMSize + 3)) * 128) - 1 : 0;
//// checksum
//if (!isChecksumOK || ((uint32) CalculatedSize > (uint32) (((1 << (ROMSize - 7)) * 128) * 1024)))
//{
// if (Settings.DisplayColor == 0xffff || Settings.DisplayColor != BUILD_PIXEL(31, 0, 0))
// {
// 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;
//IAPU.OneCycle = SNES_APU_ONE_CYCLE_SCALED;
// CPU.FastROMSpeed = 0;
// ResetSpeedMap();
// IPPU.TotalEmulatedFrames = 0;
Settings.Shutdown = Settings.ShutdownMaster;
//// 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(CompanyId, "%s", Safe(CompanyId));
//sprintf(String, "\"%s\" [%s] %s, %s, Type: %s, Mode: %s, TV: %s, S-RAM: %s, ROMId: %s Company: %2.2s CRC32: %08X",
// displayName, isChecksumOK ? "checksum ok" : ((Multi.cartType == 4) ? "no checksum" : "bad checksum"),
// MapType(), Size(), KartContents(), MapMode(), TVStandard(), StaticRAMSize(), ROMId, CompanyId, ROMCRC32);
//S9xMessage(S9X_INFO, S9X_ROM_INFO, String);
// XXX: Please remove port specific codes
#ifdef __WIN32__
#ifndef _XBOX
EnableMenuItem(GUI.hMenu, IDM_ROM_INFO, MF_ENABLED);
#endif
#ifdef RTC_DEBUGGER
if (Settings.SPC7110RTC)
EnableMenuItem(GUI.hMenu, IDM_7110_RTC, MF_ENABLED);
else
EnableMenuItem(GUI.hMenu, IDM_7110_RTC, MF_GRAYED);
#endif
#endif
Settings.ForceHiROM = Settings.ForceLoROM = FALSE;
Settings.ForceHeader = Settings.ForceNoHeader = FALSE;
Settings.ForceInterleaved = Settings.ForceNotInterleaved = Settings.ForceInterleaved2 = FALSE;
//if (stopMovie)
// S9xMovieStop(TRUE);
//if (PostRomInitFunc)
// PostRomInitFunc();
// S9xVerifyControllers();
}
#endif
void InitNewMap();
void CMemory::InitROM (bool8 Interleaved)
{
#ifndef ZSNES_FX
SuperFX.nRomBanks = CalculatedSize >> 15;
#endif
Settings.MultiPlayer5Master = Settings.MultiPlayer5;
Settings.MouseMaster = Settings.Mouse;
Settings.SuperScopeMaster = Settings.SuperScope;
Settings.DSP1Master = Settings.ForceDSP1;
Settings.SuperFX = FALSE;
Settings.SA1 = FALSE;
Settings.C4 = FALSE;
Settings.SDD1 = FALSE;
Settings.SRTC = FALSE;
Settings.SPC7110 = FALSE;
Settings.SPC7110RTC = FALSE;
Settings.BS = FALSE;//add azz 080517
#ifdef _BSX_151_
memset(ROMId, 0, 5);
memset(CompanyId, 0, 3);
uint8 *RomHeader = ROM + 0x7FB0;
if (ExtendedFormat == BIGFIRST)
RomHeader += 0x400000;
if (HiROM)
RomHeader += 0x8000;
S9xInitBSX(); // Set BS header before parsing
ParseSNESHeader(RomHeader);
Map_Initialize ();
if (Settings.BS)
{
{
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;
}
BS_151();
}
#endif
if (!Settings.BS)
{
ZeroMemory (BlockIsRAM, MEMMAP_NUM_BLOCKS);
ZeroMemory (BlockIsROM, MEMMAP_NUM_BLOCKS);
memset (ROMId, 0, 5);
memset (CompanyId, 0, 3);
}
if (!Settings.BS)
{
if (Memory.HiROM)
{
Memory.SRAMSize = ROM [0xffd8];
strncpy (ROMName, (char *) &ROM[0xffc0], ROM_NAME_LEN - 1);
ROMSpeed = ROM [0xffd5];
ROMType = ROM [0xffd6];
ROMSize = ROM [0xffd7];
ROMChecksum = ROM [0xffde] + (ROM [0xffdf] << 8);
ROMComplementChecksum = ROM [0xffdc] + (ROM [0xffdd] << 8);
memmove (ROMId, &ROM [0xffb2], 4);
memmove (CompanyId, &ROM [0xffb0], 2);
// Try to auto-detect the DSP1 chip
if (!Settings.ForceNoDSP1 &&
(ROMType & 0xf) >= 3 && (ROMType & 0xf0) == 0)
Settings.DSP1Master = TRUE;
Settings.SDD1 = Settings.ForceSDD1;
if ((ROMType & 0xf0) == 0x40)
Settings.SDD1 = !Settings.ForceNoSDD1;
Settings.SRTC = ((ROMType & 0xf0) >> 4) == 5;
if (Settings.SRTC)
S9xInitSRTC();
if (((ROMSpeed & 0x0f) == 0x0a) && ((ROMType & 0xf0) == 0xf0))
{
Settings.SPC7110 = true;
if ((ROMType & 0x0f) == 0x09)
Settings.SPC7110RTC = true;
S9xInitSPC7110();
}
if (Settings.SRTC || Settings.SPC7110RTC)
{
if (Settings.SRTC)
S9xSyncSRTC(GetCurrentTime());
else if (Settings.SPC7110RTC)
S9xSyncSPC7110RTC(GetCurrentTime());
}
if (Settings.SPC7110)
SPC7110HiROMMap();
else if (Settings.BS)
#ifdef _BSX_151_
;
#else
BSHiROMMap () ;//remove azz 080517;
#endif
else if ((ROMSpeed & ~0x10) == 0x25)
TalesROMMap (Interleaved);
else if ((ROMSpeed & ~0x10) == 0x22 &&
strncmp (ROMName, "Super Street Fighter", 20) != 0)
AlphaROMMap ();
else HiROMMap ();
}
else
{
Memory.HiROM = FALSE;
Memory.SRAMSize = ROM [0x7fd8];
ROMSpeed = ROM [0x7fd5];
ROMType = ROM [0x7fd6];
ROMSize = ROM [0x7fd7];
ROMChecksum = ROM [0x7fde] + (ROM [0x7fdf] << 8);
ROMComplementChecksum = ROM [0x7fdc] + (ROM [0x7fdd] << 8);
memmove (ROMId, &ROM [0x7fb2], 4);
memmove (CompanyId, &ROM [0x7fb0], 2);
strncpy (ROMName, (char *) &ROM[0x7fc0], ROM_NAME_LEN - 1);
Settings.SuperFX = Settings.ForceSuperFX;
if ((ROMType & 0xf0) == 0x10)
Settings.SuperFX = !Settings.ForceNoSuperFX;
// Try to auto-detect the DSP1 chip
if (!Settings.ForceNoDSP1 &&
(ROMType & 0xf) >= 3 && (ROMType & 0xf0) == 0)
Settings.DSP1Master = TRUE;
Settings.SDD1 = Settings.ForceSDD1;
if ((ROMType & 0xf0) == 0x40)
Settings.SDD1 = !Settings.ForceNoSDD1;
/*if (Settings.SDD1)
S9xLoadSDD1Data ();*/
Settings.C4 = Settings.ForceC4;
if ((ROMType & 0xf0) == 0xf0 &&
(strncmp (ROMName, "MEGAMAN X", 9) == 0 ||
strncmp (ROMName, "ROCKMAN X", 9) == 0))
Settings.C4 = !Settings.ForceNoC4;
if (Settings.SuperFX)
{
//::SRAM = ROM + 1024 * 1024 * 4;
SuperFXROMMap ();
Settings.MultiPlayer5Master = FALSE;
//Settings.MouseMaster = FALSE;
//Settings.SuperScopeMaster = FALSE;
Settings.DSP1Master = FALSE;
Settings.SA1 = FALSE;
Settings.C4 = FALSE;
Settings.SDD1 = FALSE;
}
else if (Settings.ForceSA1 ||
(!Settings.ForceNoSA1 && (ROMSpeed & ~0x10) == 0x23 &&
(ROMType & 0xf) > 3 && (ROMType & 0xf0) == 0x30))
{
Settings.SA1 = TRUE;
Settings.MultiPlayer5Master = FALSE;
//Settings.MouseMaster = FALSE;
//Settings.SuperScopeMaster = FALSE;
Settings.DSP1Master = FALSE;
Settings.C4 = FALSE;
Settings.SDD1 = FALSE;
SA1ROMMap ();
}
else if ((ROMSpeed & ~0x10) == 0x25)
TalesROMMap (Interleaved);
else if (strncmp ((char *) &ROM [0x7fc0], "SOUND NOVEL-TCOOL", 17) == 0 ||
strncmp ((char *) &ROM [0x7fc0], "DERBY STALLION 96", 17) == 0)
{
LoROM24MBSMap ();
Settings.DSP1Master = FALSE;
}
else if (strncmp ((char *) &ROM [0x7fc0], "THOROUGHBRED BREEDER3", 21) == 0 ||
strncmp ((char *) &ROM [0x7fc0], "RPG-TCOOL 2", 11) == 0)
{
SRAM512KLoROMMap ();
Settings.DSP1Master = FALSE;
}
else if (strncmp ((char *) &ROM [0x7fc0], "DEZAEMON ", 10) == 0)
{
Settings.DSP1Master = FALSE;
SRAM1024KLoROMMap ();
}
else if (strncmp ((char *) &ROM [0x7fc0], "ADD-ON BASE CASSETE", 19) == 0)
{
Settings.MultiPlayer5Master = FALSE;
Settings.MouseMaster = FALSE;
Settings.SuperScopeMaster = FALSE;
Settings.DSP1Master = FALSE;
SufamiTurboLoROMMap();
Memory.SRAMSize = 3;
}
else if ((ROMSpeed & ~0x10) == 0x22 &&
strncmp (ROMName, "Super Street Fighter", 20) != 0)
AlphaROMMap ();\
else LoROMMap ();
}
}
int power2 = 0;
int size = CalculatedSize;
while (size >>= 1)
power2++;
size = 1 << power2;
uint32 remainder = CalculatedSize - size;
/*uint32 */sum1 = 0;
/*uint32 */sum2 = 0;
int i;
for (i = 0; i < size; i++)
sum1 += ROM [i];
for (i = 0; i < (int) remainder; i++)
sum2 += ROM [size + i];
if (remainder)
{
//for Tengai makyou
if (CalculatedSize == 0x500000 && Memory.HiROM &&
strncmp ((const char *)&ROM[0xffb0], "18AZ", 4) == 0 &&
!memcmp(&ROM[0xffd5], "\x3a\xf9\x0d\x03\x00\x33\x00", 7))
sum1 += sum2;
else
sum1 += sum2 * (size / remainder);
}
sum1 &= 0xffff;
//now take a CRC32
ROMCRC32 = caCRC32(&ROM[0], CalculatedSize);
g_ROMCRC32=ROMCRC32;
if (Settings.ForceNTSC)
Settings.PAL = FALSE;
else
if (Settings.ForcePAL)
Settings.PAL = TRUE;
else
if (Memory.HiROM)
// Country code
Settings.PAL = ROM [0xffd9] >= 2;
else
Settings.PAL = ROM [0x7fd9] >= 2;
if (Settings.PAL)
{
Settings.FrameTime = Settings.FrameTimePAL;
ROMFramesPerSecond = 50;
}
else
{
Settings.FrameTime = Settings.FrameTimeNTSC;
ROMFramesPerSecond = 60;
}
ROMName[ROM_NAME_LEN - 1] = 0;
if (strlen (ROMName))
{
char *p = ROMName + strlen (ROMName) - 1;
while (p > ROMName && *(p - 1) == ' ')
p--;
*p = 0;
}
if (Settings.SuperFX)
{
SRAMMask = 0xffff;
Memory.SRAMSize = 16;
}
else
{
SRAMMask = Memory.SRAMSize ?
((1 << (Memory.SRAMSize + 3)) * 128) - 1 : 0;
}
(IAPUuncached.OneCycle) = ONE_APU_CYCLE;
Settings.Shutdown = Settings.ShutdownMaster;
ApplyROMFixes ();
#ifdef __psp__
sprintf (String, "\"%s\" [%s] %s, %s\n%s: %s, %s: %s, TV: %s, S-RAM: %s",
ROMName,
(ROMChecksum + ROMComplementChecksum != 0xffff ||
ROMChecksum != sum1) ? "bad checksum" : "checksum ok",
MapType (),
Size (),
s9xTYL_msg[TYPE],
KartContents (),
s9xTYL_msg[MODE],
MapMode (),
TVStandard (),
StaticRAMSize ());
for (i =0; i < 4; i++)
if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", ROMName[i]) == NULL) break;
if (i == 4) sprintf (String, "%s\nROMId: %s %s: %2.2s",
String, ROMId, s9xTYL_msg[COMPANY], CompanyId);
#else
sprintf (String, "\"%s\" [%s] %s, %s\nType: %s, Mode: %s, TV: %s, S-RAM: %s",
ROMName,
(ROMChecksum + ROMComplementChecksum != 0xffff ||
ROMChecksum != sum1) ? "bad checksum" : "checksum ok",
MapType (),
Size (),
KartContents (),
MapMode (),
TVStandard (),
StaticRAMSize ());
#endif
InitNewMap();
S9xMessage (0/*S9X_INFO*/, S9X_ROM_INFO, String);
}
bool8 CMemory::LoadSRTC (void)
{
/*
FILE *fp;
size_t ignore;
fp = fopen(S9xGetSaveFilename(".rtc"), "rb");
if (!fp)
return (FALSE);
ignore = fread(RTCData.reg, 1, 20, fp);
fclose(fp);
*/
return (TRUE);
}
bool8 CMemory::SaveSRTC (void)
{
/*
FILE *fp;
size_t ignore;
fp = fopen(S9xGetSaveFilename(".rtc"), "wb");
if (!fp)
return (FALSE);
ignore = fwrite(RTCData.reg, 1, 20, fp);
fclose(fp);
*/
return (TRUE);
}
bool8 CMemory::LoadSRAM (char *filename)
{
int lsize = Memory.SRAMSize ?
(1 << (Memory.SRAMSize + 3)) * 128 : 0;
memset (SRAM, SNESGameFixes.SRAMInitialValue, 0x20000);
/*debug*/
// DBG_BREAK
if (lsize > 0x20000)
lsize = 0x20000;
if (lsize)
{
FILE *file;
// STREAM SRAMFile;
// S9xMessage(1,0,filename);
if ((file = fopen (filename, "rb")))
// if ((SRAMFile = OPEN_STREAM (filename, "rb")))
{
int len = fread ((char*) SRAM, 1, 0x20000, file);
fclose (file);
// int len = READ_STREAM ((char*) SRAM, 0x20000, SRAMFile);
// CLOSE_STREAM (SRAMFile);
if (len - lsize == 512)
{
// S-RAM file has a header - remove it
memmove (SRAM, SRAM + 512, lsize);
}
if (Settings.SRTC || Settings.SPC7110RTC)
LoadSRTC();
/*
if (len == lsize + SRTC_SRAM_PAD)
{
S9xSRTCPostLoadState ();
S9xResetSRTC ();
rtc.index = -1;
rtc.mode = MODE_READ;
}
else S9xHardResetSRTC ();
*/
return (TRUE);
}
#ifdef _BSX_151_
else //add azz 080517
if (Settings.BS && !Settings.BSXItself)
{
// The BS game's SRAM was not found
// Try to read BS-X.srm instead
char path[_MAX_PATH + 1];
int size=lsize;
strcpy(path, S9xGetDirectory(SRAM_DIR));
strcat(path, SLASH_STR);
strcat(path, "BS-X.srm");
file = fopen(path, "rb");
if (file)
{
int len = fread((char *) SRAM, 1, 0x20000, file);
fclose(file);
if (len - size == 512)
memmove(SRAM, SRAM + 512, size);
#ifdef __psp__
msgBoxLines(s9xTYL_msg[SRAM_NOTFOUND], 30);
#else
S9xMessage(S9X_INFO, S9X_ROM_INFO, "The SRAM file wasn't found: BS-X.srm was read instead.");
#endif
//S9xHardResetSRTC();
return (TRUE);
}
else
{
#ifdef __psp__
msgBoxLines(s9xTYL_msg[SRAM_BSX_NOTFOUND], 30);
#else
S9xMessage(S9X_INFO, S9X_ROM_INFO, "The SRAM file wasn't found, BS-X.srm wasn't found either.");
#endif
//S9xHardResetSRTC();
return (FALSE);
}
}
#endif
//S9xHardResetSRTC ();
return (FALSE);
}
if (Settings.SDD1)
S9xSDD1LoadLoggedData ();
return (TRUE);
}
bool8 CMemory::SaveSRAM (char *filename)
{
int lsize = Memory.SRAMSize ?
(1 << (Memory.SRAMSize + 3)) * 128 : 0;
/*debug*/
// DBG_BREAK
/*
if (Settings.SRTC)
{
lsize += SRTC_SRAM_PAD;
S9xSRTCPreSaveState ();
}
*/
if (Settings.SDD1)
{
S9xSDD1SaveLoggedData ();
}
if (lsize > 0x20000)
lsize = 0x20000;
if (lsize && *ROMFilename)
{
FILE *file;
// STREAM SRAMFile;
//S9xMessage(0,0,"Saving SRAM");
if ((file = fopen (filename, "wb")))
// if ((SRAMFile = OPEN_STREAM (filename, "wb")))
{
fwrite ((char *) SRAM, lsize, 1, file);
fclose (file);
// WRITE_STREAM ((char*) SRAM, lsize, SRAMFile);
// CLOSE_STREAM (SRAMFile);
#if defined(__linux)
chown (filename, getuid (), getgid ());
#endif
if (Settings.SRTC || Settings.SPC7110RTC)
SaveSRTC();
return (TRUE);
}
}
return (FALSE);
}
void CMemory::FixROMSpeed ()
{
int c;
for (c = 0x800; c < 0x1000; c++)
{
if (BlockIsROM [c])
MemorySpeed [c] = (uint8) CPU.FastROMSpeed;
}
}
void CMemory::WriteProtectROM ()
{
memmove ((void *) WriteMap, (void *) Map, MEMMAP_NUM_BLOCKS*4);
for (int c = 0; c < 0x1000; c++)
{
if (BlockIsROM [c])
WriteMap [c] = (uint8 *) MAP_NONE;
}
}
void CMemory::MapRAM ()
{
int c;
// Banks 7e->7f, RAM
for (c = 0; c < 16; c++)
{
Map [c + 0x7e0] = RAM;
Map [c + 0x7f0] = RAM + 0x10000;
BlockIsRAM [c + 0x7e0] = TRUE;
BlockIsRAM [c + 0x7f0] = TRUE;
BlockIsROM [c + 0x7e0] = FALSE;
BlockIsROM [c + 0x7f0] = FALSE;
}
// Banks 70->77, S-RAM
for (c = 0; c < 0x80; c++)
{
Map [c + 0x700] = (uint8 *) MAP_LOROM_SRAM;
BlockIsRAM [c + 0x700] = TRUE;
BlockIsROM [c + 0x700] = FALSE;
}
}
void CMemory::MapExtraRAM ()
{
int c;
// Banks 7e->7f, RAM
for (c = 0; c < 16; c++)
{
Map [c + 0x7e0] = RAM;
Map [c + 0x7f0] = RAM + 0x10000;
BlockIsRAM [c + 0x7e0] = TRUE;
BlockIsRAM [c + 0x7f0] = TRUE;
BlockIsROM [c + 0x7e0] = FALSE;
BlockIsROM [c + 0x7f0] = FALSE;
}
// Banks 70->73, S-RAM
for (c = 0; c < 16; c++)
{
Map [c + 0x700] = ::SRAM;
Map [c + 0x710] = ::SRAM + 0x8000;
Map [c + 0x720] = ::SRAM + 0x10000;
Map [c + 0x730] = ::SRAM + 0x18000;
BlockIsRAM [c + 0x700] = TRUE;
BlockIsROM [c + 0x700] = FALSE;
BlockIsRAM [c + 0x710] = TRUE;
BlockIsROM [c + 0x710] = FALSE;
BlockIsRAM [c + 0x720] = TRUE;
BlockIsROM [c + 0x720] = FALSE;
BlockIsRAM [c + 0x730] = TRUE;
BlockIsROM [c + 0x730] = FALSE;
}
}
#ifdef _BSX_151_
//add azz 080517
void CMemory::map_WriteProtectROM (void)
{
memmove((void *) WriteMap, (void *) Map, MEMMAP_NUM_BLOCKS*4);
for (int c = 0; c < 0x1000; c++)
{
if (BlockIsROM[c])
WriteMap[c] = (uint8 *) MAP_NONE;
}
}
void CMemory::Map_Initialize (void)
{
for (int c = 0; c < 0x1000; c++)
{
Map[c] = (uint8 *) MAP_NONE;
WriteMap[c] = (uint8 *) MAP_NONE;
BlockIsROM[c] = FALSE;
BlockIsRAM[c] = FALSE;
}
}
#endif
void CMemory::LoROMMap ()
{
int c;
int i;
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = RAM;
Map [c + 1] = Map [c + 0x801] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
if (Settings.DSP1Master)
{
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP;
}
else
if (Settings.C4)
{
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_C4;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_C4;
}
else
{
Map [c + 6] = Map [c + 0x806] = (uint8 *) bytes0x2000 - 0x6000;
Map [c + 7] = Map [c + 0x807] = (uint8 *) bytes0x2000 - 0x6000;
}
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = &ROM [(c << 11) % CalculatedSize] - 0x8000;
BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i] =
MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
if (Settings.DSP1Master)
{
// Banks 30->3f and b0->bf
for (c = 0x300; c < 0x400; c += 16)
{
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = (uint8 *) MAP_DSP;
BlockIsROM [i] = BlockIsROM [i + 0x800] = FALSE;
}
}
}
// Banks 40->7f and c0->ff
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 8; i++)
Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) % CalculatedSize];
for (i = c + 8; i < c + 16; i++)
Map [i + 0x400] = Map [i + 0xc00] = &ROM [((c << 11) + 0x200000) % CalculatedSize - 0x8000];
for (i = c; i < c + 16; i++)
{
MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE;
BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
}
}
if (Settings.DSP1Master)
{
for (c = 0; c < 0x100; c++)
{
Map [c + 0xe00] = (uint8 *) MAP_DSP;
MemorySpeed [c + 0xe00] = SLOW_ONE_CYCLE;
BlockIsROM [c + 0xe00] = FALSE;
}
}
MapRAM ();
WriteProtectROM ();
}
void CMemory::HiROMMap ()
{
int c;
int i;
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
Map [c + 1] = Map [c + 0x801] = RAM;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
if (Settings.DSP1Master)
{
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP;
}
else
{
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
}
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = &ROM [(c << 12) % CalculatedSize];
BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i] =
MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
// Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM.
for (c = 0; c < 16; c++)
{
Map [0x306 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
Map [0x307 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
Map [0xb06 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
Map [0xb07 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
BlockIsRAM [0x306 + (c << 4)] = TRUE;
BlockIsRAM [0x307 + (c << 4)] = TRUE;
BlockIsRAM [0xb06 + (c << 4)] = TRUE;
BlockIsRAM [0xb07 + (c << 4)] = TRUE;
}
// Banks 40->7f and c0->ff
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 16; i++)
{
Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE;
BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
}
}
MapRAM ();
WriteProtectROM ();
}
void CMemory::TalesROMMap (bool8 Interleaved)
{
int c;
int i;
uint32 OFFSET0 = 0x400000;
uint32 OFFSET1 = 0x400000;
uint32 OFFSET2 = 0x000000;
if (Interleaved)
{
OFFSET0 = 0x000000;
OFFSET1 = 0x000000;
OFFSET2 = 0x200000;
}
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = RAM;
Map [c + 1] = Map [c + 0x801] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
for (i = c + 8; i < c + 16; i++)
{
Map [i] = &ROM [((c << 12) + OFFSET0) % CalculatedSize];
Map [i + 0x800] = &ROM [((c << 12) + OFFSET0) % CalculatedSize];
BlockIsROM [i] = TRUE;
BlockIsROM [i + 0x800] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i] =
MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
// Banks 30->3f and b0->bf, address ranges 6000->7ffff is S-RAM.
for (c = 0; c < 16; c++)
{
Map [0x306 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
Map [0x307 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
Map [0xb06 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
Map [0xb07 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
BlockIsRAM [0x306 + (c << 4)] = TRUE;
BlockIsRAM [0x307 + (c << 4)] = TRUE;
BlockIsRAM [0xb06 + (c << 4)] = TRUE;
BlockIsRAM [0xb07 + (c << 4)] = TRUE;
}
// Banks 40->7f and c0->ff
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 8; i++)
{
Map [i + 0x400] = &ROM [((c << 12) + OFFSET1) % CalculatedSize];
Map [i + 0x408] = &ROM [((c << 12) + OFFSET1) % CalculatedSize];
Map [i + 0xc00] = &ROM [((c << 12) + OFFSET2) % CalculatedSize];
Map [i + 0xc08] = &ROM [((c << 12) + OFFSET2) % CalculatedSize];
BlockIsROM [i + 0x400] = TRUE;
BlockIsROM [i + 0x408] = TRUE;
BlockIsROM [i + 0xc00] = TRUE;
BlockIsROM [i + 0xc08] = TRUE;
MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE;
MemorySpeed [i + 0x408] = MemorySpeed [i + 0xc08] = SLOW_ONE_CYCLE;
}
}
MapRAM ();
WriteProtectROM ();
}
void CMemory::AlphaROMMap ()
{
int c;
int i;
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = RAM;
Map [c + 1] = Map [c + 0x801] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP;
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
BlockIsROM [i] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i] =
MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
// Banks 40->7f and c0->ff
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 16; i++)
{
Map [i + 0x400] = &ROM [(c << 12) % CalculatedSize];
Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE;
BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
}
}
MapRAM ();
WriteProtectROM ();
}
void DetectSuperFxRamSize()
{
if(Memory.ROM[0x7FDA]==0x33)
{
Memory.SRAMSize=Memory.ROM[0x7FBD];
}
else
{
if(strncmp(Memory.ROMName, "STAR FOX 2", 10)==0)
{
Memory.SRAMSize=6;
}
else Memory.SRAMSize=5;
}
}
void CMemory::SuperFXROMMap ()
{
int c;
int i;
DetectSuperFxRamSize();
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = RAM;
Map [c + 1] = Map [c + 0x801] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
Map [0x006 + c] = Map [0x806 + c] = (uint8 *) ::SRAM - 0x6000;
Map [0x007 + c] = Map [0x807 + c] = (uint8 *) ::SRAM - 0x6000;
BlockIsRAM [0x006 + c] = BlockIsRAM [0x007 + c] = BlockIsRAM [0x806 + c] = BlockIsRAM [0x807 + c] = TRUE;
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
}
}
// Banks 40->7f and c0->ff
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 16; i++)
{
Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
}
}
// Banks 7e->7f, RAM
for (c = 0; c < 16; c++)
{
Map [c + 0x7e0] = RAM;
Map [c + 0x7f0] = RAM + 0x10000;
BlockIsRAM [c + 0x7e0] = TRUE;
BlockIsRAM [c + 0x7f0] = TRUE;
BlockIsROM [c + 0x7e0] = FALSE;
BlockIsROM [c + 0x7f0] = FALSE;
}
// Banks 70->71, S-RAM
for (c = 0; c < 32; c++)
{
Map [c + 0x700] = ::SRAM + (((c >> 4) & 1) << 16);
BlockIsRAM [c + 0x700] = TRUE;
BlockIsROM [c + 0x700] = FALSE;
}
// Replicate the first 2Mb of the ROM at ROM + 2MB such that each 32K
// block is repeated twice in each 64K block.
for (c = 0; c < 64; c++)
{
memmove (&ROM [0x200000 + c * 0x10000], &ROM [c * 0x8000], 0x8000);
memmove (&ROM [0x208000 + c * 0x10000], &ROM [c * 0x8000], 0x8000);
}
WriteProtectROM ();
}
void CMemory::SA1ROMMap ()
{
int c;
int i;
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = RAM;
Map [c + 1] = Map [c + 0x801] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = (uint8 *) &ROM_GLOBAL [0x3000] - 0x3000;
Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_BWRAM;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_BWRAM;
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i] =
MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
// Banks 40->7f
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 16; i++)
Map [i + 0x400] = (uint8 *) &SRAM [(c << 12) & 0x1ffff];
for (i = c; i < c + 16; i++)
{
MemorySpeed [i + 0x400] = SLOW_ONE_CYCLE;
BlockIsROM [i + 0x400] = FALSE;
}
}
// c0->ff
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 16; i++)
{
Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE;
BlockIsROM [i + 0xc00] = TRUE;
}
}
for (c = 0; c < 16; c++)
{
Map [c + 0x7e0] = RAM;
Map [c + 0x7f0] = RAM + 0x10000;
BlockIsRAM [c + 0x7e0] = TRUE;
BlockIsRAM [c + 0x7f0] = TRUE;
BlockIsROM [c + 0x7e0] = FALSE;
BlockIsROM [c + 0x7f0] = FALSE;
}
WriteProtectROM ();
// Now copy the map and correct it for the SA1 CPU.
memmove ((void *) SA1.WriteMap, (void *) WriteMap, sizeof (WriteMap));
memmove ((void *) SA1.Map, (void *) Map, MEMMAP_NUM_BLOCKS*4);
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
SA1.Map [c + 0] = SA1.Map [c + 0x800] = &ROM_GLOBAL [0x3000];
SA1.Map [c + 1] = SA1.Map [c + 0x801] = (uint8 *) MAP_NONE;
SA1.WriteMap [c + 0] = SA1.WriteMap [c + 0x800] = &ROM_GLOBAL [0x3000];
SA1.WriteMap [c + 1] = SA1.WriteMap [c + 0x801] = (uint8 *) MAP_NONE;
}
// Banks 60->6f
for (c = 0; c < 0x100; c++)
SA1.Map [c + 0x600] = SA1.WriteMap [c + 0x600] = (uint8 *) MAP_BWRAM_BITMAP;
BWRAM = SRAM;
}
void CMemory::LoROM24MBSMap ()
{
int c;
int i;
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = RAM;
Map [c + 1] = Map [c + 0x801] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i] =
MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
// Banks 00->3f and 80->bf
for (c = 0; c < 0x200; c += 16)
{
Map [c + 0x800] = RAM;
Map [c + 0x801] = RAM;
BlockIsRAM [c + 0x800] = TRUE;
BlockIsRAM [c + 0x801] = TRUE;
Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 0x803] = (uint8 *) MAP_PPU;
Map [c + 0x804] = (uint8 *) MAP_CPU;
Map [c + 0x805] = (uint8 *) MAP_CPU;
Map [c + 0x806] = (uint8 *) MAP_NONE;
Map [c + 0x807] = (uint8 *) MAP_NONE;
for (i = c + 8; i < c + 16; i++)
{
Map [i + 0x800] = &ROM [c << 11] - 0x8000 + 0x200000;
BlockIsROM [i + 0x800] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
// Banks 40->7f and c0->ff
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 8; i++)
Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000];
for (i = c + 8; i < c + 16; i++)
Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000 - 0x8000];
for (i = c; i < c + 16; i++)
{
MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE;
BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
}
}
MapExtraRAM ();
WriteProtectROM ();
}
void CMemory::SufamiTurboLoROMMap ()
{
int c;
int i;
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = RAM;
Map [c + 1] = Map [c + 0x801] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
if (Settings.DSP1Master)
{
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP;
}
else
{
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
}
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i] =
MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
if (Settings.DSP1Master)
{
// Banks 30->3f and b0->bf
for (c = 0x300; c < 0x400; c += 16)
{
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = (uint8 *) MAP_DSP;
BlockIsROM [i] = BlockIsROM [i + 0x800] = FALSE;
}
}
}
// Banks 40->7f and c0->ff
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 8; i++)
Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000];
for (i = c + 8; i < c + 16; i++)
Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000 - 0x8000];
for (i = c; i < c + 16; i++)
{
MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE;
BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
}
}
if (Settings.DSP1Master)
{
for (c = 0; c < 0x100; c++)
{
Map [c + 0xe00] = (uint8 *) MAP_DSP;
MemorySpeed [c + 0xe00] = SLOW_ONE_CYCLE;
BlockIsROM [c + 0xe00] = FALSE;
}
}
// Banks 7e->7f, RAM
for (c = 0; c < 16; c++)
{
Map [c + 0x7e0] = RAM;
Map [c + 0x7f0] = RAM + 0x10000;
BlockIsRAM [c + 0x7e0] = TRUE;
BlockIsRAM [c + 0x7f0] = TRUE;
BlockIsROM [c + 0x7e0] = FALSE;
BlockIsROM [c + 0x7f0] = FALSE;
}
// Banks 60->67, S-RAM
for (c = 0; c < 0x80; c++)
{
Map [c + 0x600] = (uint8 *) MAP_LOROM_SRAM;
BlockIsRAM [c + 0x600] = TRUE;
BlockIsROM [c + 0x600] = FALSE;
}
WriteProtectROM ();
}
void CMemory::SRAM512KLoROMMap ()
{
int c;
int i;
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = RAM;
Map [c + 1] = Map [c + 0x801] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000;
BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i] =
MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
// Banks 40->7f and c0->ff
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 8; i++)
Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000];
for (i = c + 8; i < c + 16; i++)
Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000 - 0x8000];
for (i = c; i < c + 16; i++)
{
MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE;
BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
}
}
MapExtraRAM ();
WriteProtectROM ();
}
void CMemory::SRAM1024KLoROMMap ()
{
int c;
int i;
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = Map [c + 0x400] = Map [c + 0xc00] = RAM;
Map [c + 1] = Map [c + 0x801] = Map [c + 0x401] = Map [c + 0xc01] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = BlockIsRAM [c + 0x400] = BlockIsRAM [c + 0xc00] = TRUE;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = BlockIsRAM [c + 0x401] = BlockIsRAM [c + 0xc01] = TRUE;
Map [c + 2] = Map [c + 0x802] = Map [c + 0x402] = Map [c + 0xc02] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = Map [c + 0x403] = Map [c + 0xc03] = (uint8 *) MAP_PPU;
Map [c + 4] = Map [c + 0x804] = Map [c + 0x404] = Map [c + 0xc04] = (uint8 *) MAP_CPU;
Map [c + 5] = Map [c + 0x805] = Map [c + 0x405] = Map [c + 0xc05] = (uint8 *) MAP_CPU;
Map [c + 6] = Map [c + 0x806] = Map [c + 0x406] = Map [c + 0xc06] = (uint8 *) MAP_NONE;
Map [c + 7] = Map [c + 0x807] = Map [c + 0x407] = Map [c + 0xc07] = (uint8 *) MAP_NONE;
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = Map [i + 0x400] = Map [i + 0xc00] = &ROM [c << 11] - 0x8000;
BlockIsROM [i] = BlockIsROM [i + 0x800] = BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i] = MemorySpeed [i + 0x800] =
MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
MapExtraRAM ();
WriteProtectROM ();
}
void CMemory::BSHiROMMap ()
{
int c;
int i;
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
Map [c + 1] = Map [c + 0x801] = RAM;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
// XXX: How large is SRAM??
Map [c + 5] = Map [c + 0x805] = (uint8 *) SRAM;
BlockIsRAM [c + 5] = BlockIsRAM [c + 0x805] = TRUE;
Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE;
Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE;
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = &ROM [(c << 12) % CalculatedSize];
BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i] =
MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
// Banks 60->7d offset 0000->7fff & 60->7f offset 8000->ffff PSRAM
// XXX: How large is PSRAM?
for (c = 0x600; c < 0x7e0; c += 16)
{
for (i = c; i < c + 8; i++)
{
Map [i] = &ROM [0x400000 + (c << 11)];
BlockIsRAM [i] = TRUE;
}
for (i = c + 8; i < c + 16; i++)
{
Map [i] = &ROM [0x400000 + (c << 11) - 0x8000];
BlockIsRAM [i] = TRUE;
}
}
// Banks 40->7f and c0->ff
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 16; i++)
{
Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE;
BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
}
}
MapRAM ();
WriteProtectROM ();
}
void CMemory::SPC7110HiROMMap ()
{
int c;
int i;
// Banks 00->3f and 80->bf
for (c = 0; c < 0x400; c += 16)
{
Map [c + 0] = Map [c + 0x800] = RAM;
BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE;
Map [c + 1] = Map [c + 0x801] = RAM;
BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE;
Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU;
Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU;
Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU;
Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU;
Map [c + 6] = (uint8 *) MAP_HIROM_SRAM;
Map [c + 7] = (uint8 *) MAP_HIROM_SRAM;
Map [c + 0x806] = Map [c + 0x807]= (uint8 *) MAP_NONE;
for (i = c + 8; i < c + 16; i++)
{
Map [i] = Map [i + 0x800] = &ROM [(c << 12) % CalculatedSize];
BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE;
}
for (i = c; i < c + 16; i++)
{
int ppu = i & 15;
MemorySpeed [i] =
MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE;
}
}
// Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM.
for (c = 0; c < 16; c++)
{
Map [0x306 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
Map [0x307 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM;
Map [0xb06 + (c << 4)] = (uint8 *) MAP_NONE;
Map [0xb07 + (c << 4)] = (uint8 *) MAP_NONE;
BlockIsRAM [0x306 + (c << 4)] = TRUE;
BlockIsRAM [0x307 + (c << 4)] = TRUE;
// BlockIsRAM [0xb06 + (c << 4)] = TRUE;
// BlockIsRAM [0xb07 + (c << 4)] = TRUE;
}
// Banks 40->7f and c0->ff
for (c = 0; c < 0x400; c += 16)
{
for (i = c; i < c + 16; i++)
{
Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize];
MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE;
BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE;
}
}
for (c = 0; c < 0x10; c++)
{
Map [0x500 + c] = (uint8 *) MAP_SPC7110_DRAM;
BlockIsROM [0x500 + c] = TRUE;
}
for (c = 0; c < 0x100; c++)
{
Map [0xD00 + c] = (uint8 *) MAP_SPC7110_ROM;
Map [0xE00 + c] = (uint8 *) MAP_SPC7110_ROM;
Map [0xF00 + c] = (uint8 *) MAP_SPC7110_ROM;
BlockIsROM [0xD00 + c] = BlockIsROM [0xE00 + c] = BlockIsROM [0xF00 + c] = TRUE;
}
MapRAM ();
WriteProtectROM ();
}
const char *CMemory::TVStandard ()
{
return (Settings.PAL ? "PAL" : "NTSC");
}
const char *CMemory::Speed ()
{
return (ROMSpeed & 0x10 ? "120ns" : "200ns");
}
const char *CMemory::MapType ()
{
return (HiROM ? "HiROM" : "LoROM");
}
const char *CMemory::StaticRAMSize ()
{
static char tmp [20];
if (Memory.SRAMSize > 16)
#ifdef __psp__
return s9xTYL_msg[CORRUPT];
#else
return ("Corrupt");
#endif
sprintf (tmp, "%dKb", (SRAMMask + 1) / 1024);
return (tmp);
}
const char *CMemory::Size ()
{
static char tmp [20];
if (ROMSize < 7 || ROMSize - 7 > 23)
#ifdef __psp__
return s9xTYL_msg[CORRUPT];
#else
return ("Corrupt");
#endif
sprintf (tmp, "%dMbits", 1 << (ROMSize - 7));
return (tmp);
}
const char *CMemory::KartContents ()
{
static char tmp [30];
static const char *CoPro [16] = {
"DSP1", "SuperFX", "OBC1", "SA-1", "S-DD1", "S-RTC", "CoPro#6",
"CoPro#7", "CoPro#8", "CoPro#9", "CoPro#10", "CoPro#11", "CoPro#12",
"CoPro#13", "CoPro#14", "CoPro-Custom"
};
static const char *Contents [3] = {
"ROM", "ROM+RAM", "ROM+RAM+BAT"
};
if (ROMType == 0)
#ifdef __psp__
return s9xTYL_msg[ROM_ONLY];
#else
return ("ROM only");
#endif
sprintf (tmp, "%s", Contents [(ROMType & 0xf) % 3]);
if (Settings.SPC7110 && Settings.SPC7110RTC)
sprintf (tmp, "%s+%s", tmp, "SPC7110+RTC");
else if (Settings.SPC7110)
sprintf (tmp, "%s+%s", tmp, "SPC7110");
else if ((ROMType & 0xf) >= 3)
sprintf (tmp, "%s+%s", tmp, CoPro [(ROMType & 0xf0) >> 4]);
return (tmp);
}
const char *CMemory::MapMode ()
{
static char tmp [4];
sprintf (tmp, "%02x", ROMSpeed & ~0x10);
return (tmp);
}
const char *CMemory::ROMID ()
{
return (ROMId);
}
void CMemory::ApplyROMFixes ()
{
// Enable S-RTC (Real Time Clock) emulation for Dai Kaijyu Monogatari 2
//Settings.SRTC = ((ROMType & 0xf0) >> 4) == 5;
//Settings.SRTC = (((ROMType & 0xff) << 8) + (ROMSpeed & 0xff))==0x5535;
Settings.StrikeGunnerOffsetHack = strcmp (ROMName, "STRIKE GUNNER") == 0 ? 7 : 0;
CPU.NMITriggerPoint = 4;
if (strcmp (ROMName, "CACOMA KNIGHT") == 0)
CPU.NMITriggerPoint = 25;
// These games complain if the multi-player adaptor is 'connected'
if (strcmp (ROMName, "TETRIS&Dr.MARIO") == 0 ||
strcmp (ROMName, "JIGSAW PARTY") == 0 ||
strcmp (ROMName, "SUPER PICROSS") == 0 ||
strcmp (ROMName, "KIRBY NO KIRA KIZZU") == 0 ||
strcmp (ROMName, "BLOCK") == 0 ||
strncmp (ROMName, "SUPER BOMBLISS", 14) == 0 ||
strcmp (ROMId, "ABOJ") == 0)
{
Settings.MultiPlayer5Master = FALSE;
Settings.MouseMaster = FALSE;
Settings.SuperScopeMaster = FALSE;
}
// Games which spool sound samples between the SNES and sound CPU using
// H-DMA as the sample is playing.
if (strcmp (ROMName, "EARTHWORM JIM 2") == 0 ||
strcmp (ROMName, "PRIMAL RAGE") == 0 ||
strcmp (ROMName, "CLAY FIGHTER") == 0 ||
strcmp (ROMName, "ClayFighter 2") == 0 ||
strncasecmp (ROMName, "MADDEN", 6) == 0 ||
strncmp (ROMName, "NHL", 3) == 0 ||
strcmp (ROMName, "WeaponLord") == 0)
{
Settings.Shutdown = FALSE;
}
// Stunt Racer FX
if (strcmp (ROMId, "CQ ") == 0 ||
// Illusion of Gaia
strncmp (ROMId, "JG", 2) == 0 ||
strcmp (ROMName, "GAIA GENSOUKI 1 JPN") == 0)
{
(IAPUuncached.OneCycle) = 13;
}
// RENDERING RANGER R2
if (strcmp (ROMId, "AVCJ") == 0 ||
// Star Ocean
strncmp (ROMId, "ARF", 3) == 0 ||
// Tales of Phantasia
strncmp (ROMId, "ATV", 3) == 0 ||
// Act Raiser 1 & 2
strncasecmp (ROMName, "ACTRAISER", 9) == 0 ||
// Soulblazer
strcmp (ROMName, "SOULBLAZER - 1 USA") == 0 ||
strncmp (ROMName, "SOULBLAZER 1",12) == 0 ||
strcmp (ROMName, "SOULBLADER - 1") == 0 ||
// Terranigma
strncmp (ROMId, "AQT", 3) == 0 ||
// Robotrek
strncmp (ROMId, "E9 ", 3) == 0 ||
strcmp (ROMName, "SLAP STICK 1 JPN") == 0 ||
// ZENNIHON PURORESU2
strncmp (ROMId, "APR", 3) == 0 ||
// Bomberman 4
strncmp (ROMId, "A4B", 3) == 0 ||
// UFO KAMEN YAKISOBAN
strncmp (ROMId, "Y7 ", 3) == 0 ||
strncmp (ROMId, "Y9 ", 3) == 0 ||
// Panic Bomber World
strncmp (ROMId, "APB", 3) == 0 ||
((strncmp (ROMName, "Parlor", 6) == 0 ||
strcmp (ROMName, "HEIWA Parlor!Mini8") == 0 ||
strncmp (ROMName, "SANKYO Fever! ̨°ÊÞ°!", 21) == 0) &&
strcmp (CompanyId, "A0") == 0) ||
strcmp (ROMName, "DARK KINGDOM") == 0 ||
strcmp (ROMName, "ZAN3 SFC") == 0 ||
strcmp (ROMName, "HIOUDEN") == 0 ||
strcmp (ROMName, "ÃݼɳÀ") == 0 ||
strcmp (ROMName, "FORTUNE QUEST") == 0 ||
strcmp (ROMName, "FISHING TO BASSING") == 0 ||
strncmp (ROMName, "TokyoDome '95Battle 7", 21) == 0 ||
strcmp (ROMName, "OHMONO BLACKBASS") == 0)
{
(IAPUuncached.OneCycle) = 15;
}
if (strcmp (ROMName, "BATMAN--REVENGE JOKER") == 0)
{
Memory.HiROM = FALSE;
Memory.LoROM = TRUE;
LoROMMap ();
}
Settings.StarfoxHack = strcmp (ROMName, "STAR FOX") == 0 ||
strcmp (ROMName, "STAR WING") == 0;
Settings.WinterGold = strcmp (ROMName, "FX SKIING NINTENDO 96") == 0 ||
strcmp (ROMName, "DIRT RACER") == 0 ||
strcmp (ROMName, "Stunt Race FX") == 0 ||
Settings.StarfoxHack;
Settings.ChuckRock = strcmp (ROMName, "CHUCK ROCK") == 0;
Settings.Dezaemon = strcmp (ROMName, "DEZAEMON") == 0;
if (strcmp (ROMName, "RADICAL DREAMERS") == 0 ||
strcmp (ROMName, "TREASURE CONFLIX") == 0)
{
int c;
for (c = 0; c < 0x80; c++)
{
Map [c + 0x700] = ROM + 0x200000 + 0x1000 * (c & 0xf0);
BlockIsRAM [c + 0x700] = TRUE;
BlockIsROM [c + 0x700] = FALSE;
}
for (c = 0; c < 0x400; c += 16)
{
Map [c + 5] = Map [c + 0x805] = ROM + 0x300000;
BlockIsRAM [c + 5] = BlockIsRAM [c + 0x805] = TRUE;
}
WriteProtectROM ();
}
Settings.H_Max = (SNES_CYCLES_PER_SCANLINE *
Settings.CyclesPercentage) / 100;
if (strcmp (ROMId, "ASRJ") == 0 && Settings.CyclesPercentage == 100)
// Street Racer
Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 95) / 100;
// Power Rangers Fight
if (strncmp (ROMId, "A3R", 3) == 0 ||
// Clock Tower
strncmp (ROMId, "AJE", 3) == 0)
Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 103) / 100;
if (strcmp (ROMId, "AWVP") == 0 || strcmp (ROMId, "AWVE") == 0 ||
strcmp (ROMId, "AWVJ") == 0)
{
// Wrestlemania Arcade
#if 0
if (Settings.CyclesPercentage == 100)
Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 140) / 100; // Fixes sound
#endif
Settings.WrestlemaniaArcade = TRUE;
}
// Theme Park - disable offset-per-tile mode.
if (strcmp (ROMId, "ATQP") == 0)
Settings.WrestlemaniaArcade = TRUE;
if (strncmp (ROMId, "A3M", 3) == 0 && Settings.CyclesPercentage == 100)
// Mortal Kombat 3. Fixes cut off speech sample
Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 110) / 100;
if (strcmp (ROMName, "\x0bd\x0da\x0b2\x0d4\x0b0\x0bd\x0de") == 0 &&
Settings.CyclesPercentage == 100)
Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 101) / 100;
if (strcmp (ROMName, "WILD TRAX") == 0 ||
strcmp (ROMName, "YOSSY'S ISLAND") == 0 ||
strcasecmp (ROMName, "YOSHI'S ISLAND") == 0)
CPU.TriedInterleavedMode2 = TRUE;
// Start Trek: Deep Sleep 9
if (strncmp (ROMId, "A9D", 3) == 0 && Settings.CyclesPercentage == 100)
Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 110) / 100;
Settings.APURAMInitialValue = 0xff;
if (strcmp (ROMName, "·­³Ô¸¥Ò¶ÞÐÃݾ²") == 0 ||
strcmp (ROMName, "KENTOUOU WORLDCHAMPIO") == 0 ||
strcmp (ROMName, "TKO SUPERCHAMPIONSHIP") == 0 ||
strcmp (ROMName, "TKO SUPER CHAMPIONSHI") == 0 ||
strcmp (ROMName, "IHATOVO STORY") == 0 ||
strcmp (ROMName, "WANDERERS FROM YS") == 0 ||
strcmp (ROMName, "SUPER GENTYOUHISHI") == 0 ||
// Panic Bomber World
strncmp (ROMId, "APB", 3) == 0)
{
Settings.APURAMInitialValue = 0;
}
Settings.DaffyDuck = strcmp (ROMName, "DAFFY DUCK: MARV MISS") == 0;
Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX;
SA1.WaitAddress = NULL;
SA1.WaitByteAddress1 = NULL;
SA1.WaitByteAddress2 = NULL;
/* Bass Fishing */
if (strcmp (ROMId, "ZBPJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x0093f1 >> MEMMAP_SHIFT] + 0x93f1;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x304a;
}
/* DAISENRYAKU EXPERTWW2 */
if (strcmp (ROMId, "AEVJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x0ed18d >> MEMMAP_SHIFT] + 0xd18d;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x3000;
}
/* debjk2 */
if (strcmp (ROMId, "A2DJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x008b62 >> MEMMAP_SHIFT] + 0x8b62;
}
/* Dragon Ballz HD */
if (strcmp (ROMId, "AZIJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x008083 >> MEMMAP_SHIFT] + 0x8083;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x3020;
}
/* SFC SDGUNDAMGNEXT */
if (strcmp (ROMId, "ZX3J") == 0)
{
SA1.WaitAddress = SA1.Map [0x0087f2 >> MEMMAP_SHIFT] + 0x87f2;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x30c4;
}
/* ShougiNoHanamichi */
if (strcmp (ROMId, "AARJ") == 0)
{
SA1.WaitAddress = SA1.Map [0xc1f85a >> MEMMAP_SHIFT] + 0xf85a;
SA1.WaitByteAddress1 = SRAM + 0x0c64;
SA1.WaitByteAddress2 = SRAM + 0x0c66;
}
/* KATO HIFUMI9DAN SYOGI */
if (strcmp (ROMId, "A23J") == 0)
{
SA1.WaitAddress = SA1.Map [0xc25037 >> MEMMAP_SHIFT] + 0x5037;
SA1.WaitByteAddress1 = SRAM + 0x0c06;
SA1.WaitByteAddress2 = SRAM + 0x0c08;
}
/* idaten */
if (strcmp (ROMId, "AIIJ") == 0)
{
SA1.WaitAddress = SA1.Map [0xc100be >> MEMMAP_SHIFT] + 0x00be;
SA1.WaitByteAddress1 = SRAM + 0x1002;
SA1.WaitByteAddress2 = SRAM + 0x1004;
}
/* igotais */
if (strcmp (ROMId, "AITJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x0080b7 >> MEMMAP_SHIFT] + 0x80b7;
}
/* J96 DREAM STADIUM */
if (strcmp (ROMId, "AJ6J") == 0)
{
SA1.WaitAddress = SA1.Map [0xc0f74a >> MEMMAP_SHIFT] + 0xf74a;
}
/* JumpinDerby */
if (strcmp (ROMId, "AJUJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x00d926 >> MEMMAP_SHIFT] + 0xd926;
}
/* JKAKINOKI SHOUGI */
if (strcmp (ROMId, "AKAJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x00f070 >> MEMMAP_SHIFT] + 0xf070;
}
/* HOSHI NO KIRBY 3 & KIRBY'S DREAM LAND 3 JAP & US */
if (strcmp (ROMId, "AFJJ") == 0 || strcmp (ROMId, "AFJE") == 0)
{
SA1.WaitAddress = SA1.Map [0x0082d4 >> MEMMAP_SHIFT] + 0x82d4;
SA1.WaitByteAddress1 = SRAM + 0x72a4;
}
/* KIRBY SUPER DELUXE JAP */
if (strcmp (ROMId, "AKFJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x008c93 >> MEMMAP_SHIFT] + 0x8c93;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x300a;
SA1.WaitByteAddress2 = ROM_GLOBAL + 0x300e;
}
/* KIRBY SUPER DELUXE US */
if (strcmp (ROMId, "AKFE") == 0)
{
SA1.WaitAddress = SA1.Map [0x008cb8 >> MEMMAP_SHIFT] + 0x8cb8;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x300a;
SA1.WaitByteAddress2 = ROM_GLOBAL + 0x300e;
}
/* SUPER MARIO RPG JAP & US */
if (strcmp (ROMId, "ARWJ") == 0 || strcmp (ROMId, "ARWE") == 0)
{
SA1.WaitAddress = SA1.Map [0xc0816f >> MEMMAP_SHIFT] + 0x816f;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x3000;
}
/* marvelous.zip */
if (strcmp (ROMId, "AVRJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x0085f2 >> MEMMAP_SHIFT] + 0x85f2;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x3024;
}
/* AUGUSTA3 MASTERS NEW */
if (strcmp (ROMId, "AO3J") == 0)
{
SA1.WaitAddress = SA1.Map [0x00dddb >> MEMMAP_SHIFT] + 0xdddb;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x37b4;
}
/* OSHABERI PARODIUS */
if (strcmp (ROMId, "AJOJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x8084e5 >> MEMMAP_SHIFT] + 0x84e5;
}
/* PANIC BOMBER WORLD */
if (strcmp (ROMId, "APBJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x00857a >> MEMMAP_SHIFT] + 0x857a;
}
/* PEBBLE BEACH NEW */
if (strcmp (ROMId, "AONJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x00df33 >> MEMMAP_SHIFT] + 0xdf33;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x37b4;
}
/* PGA EUROPEAN TOUR */
if (strcmp (ROMId, "AEPE") == 0)
{
SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x3102;
}
/* PGA TOUR 96 */
if (strcmp (ROMId, "A3GE") == 0)
{
SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x3102;
}
/* POWER RANGERS 4 */
if (strcmp (ROMId, "A4RE") == 0)
{
SA1.WaitAddress = SA1.Map [0x009899 >> MEMMAP_SHIFT] + 0x9899;
SA1.WaitByteAddress1 = ROM_GLOBAL + 0x3000;
}
/* PACHISURO PALUSUPE */
if (strcmp (ROMId, "AGFJ") == 0)
{
// Never seems to turn on the SA-1!
}
/* SD F1 GRAND PRIX */
if (strcmp (ROMId, "AGFJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x0181bc >> MEMMAP_SHIFT] + 0x81bc;
}
/* SHOUGI MARJONG */
if (strcmp (ROMId, "ASYJ") == 0)
{
SA1.WaitAddress = SA1.Map [0x00f2cc >> MEMMAP_SHIFT] + 0xf2cc;
SA1.WaitByteAddress1 = SRAM + 0x7ffe;
SA1.WaitByteAddress2 = SRAM + 0x7ffc;
}
/* shogisai2 */
if (strcmp (ROMId, "AX2J") == 0)
{
SA1.WaitAddress = SA1.Map [0x00d675 >> MEMMAP_SHIFT] + 0xd675;
}
/* SHINING SCORPION */
if (strcmp (ROMId, "A4WJ") == 0)
{
SA1.WaitAddress = SA1.Map [0xc048be >> MEMMAP_SHIFT] + 0x48be;
}
/* SHIN SHOUGI CLUB */
if (strcmp (ROMId, "AHJJ") == 0)
{
SA1.WaitAddress = SA1.Map [0xc1002a >> MEMMAP_SHIFT] + 0x002a;
SA1.WaitByteAddress1 = SRAM + 0x0806;
SA1.WaitByteAddress2 = SRAM + 0x0808;
}
// Additional game fixes by sanmaiwashi ...
if (strcmp (ROMName, "SFX ŲĶÞÝÀÞÑÓɶÞÀØ 1") == 0)
{
bytes0x2000 [0xb18] = 0x4c;
bytes0x2000 [0xb19] = 0x4b;
bytes0x2000 [0xb1a] = 0xea;
}
if (strcmp (ROMName, "GOGO ACKMAN3") == 0 ||
strcmp (ROMName, "HOME ALONE") == 0)
{
// Banks 00->3f and 80->bf
for (int c = 0; c < 0x400; c += 16)
{
Map [c + 6] = Map [c + 0x806] = SRAM;
Map [c + 7] = Map [c + 0x807] = SRAM;
BlockIsROM [c + 6] = BlockIsROM [c + 0x806] = FALSE;
BlockIsROM [c + 7] = BlockIsROM [c + 0x807] = FALSE;
BlockIsRAM [c + 6] = BlockIsRAM [c + 0x806] = TRUE;
BlockIsRAM [c + 7] = BlockIsRAM [c + 0x807] = TRUE;
}
WriteProtectROM ();
}
if (strncmp (ROMName, "SWORD WORLD SFC", 15) == 0 ||
strcmp (ROMName, "SFC ¶ÒÝײÀÞ°") == 0)
{
(IAPUuncached.OneCycle) = 15;
SNESGameFixes.NeedInit0x2137 = TRUE;
}
if (strncmp (ROMName, "SHIEN THE BLADE CHASE", 21) == 0)
SNESGameFixes.Old_Read0x4200 = TRUE;
if (strcmp (ROMName, "ºÞ¼Þ× ¶²¼Þ­³ÀÞ²¹¯¾Ý") == 0)
SNESGameFixes.NeedInit0x2137 = TRUE;
if (strcmp (ROMName, "UMIHARAKAWASE") == 0)
SNESGameFixes.umiharakawaseFix = TRUE;
if (strcmp (ROMName, "ALIENS vs. PREDATOR") == 0)
SNESGameFixes.alienVSpredetorFix = TRUE;
if (strcmp (ROMName, "demon's blazon") == 0 ||
strcmp (ROMName, "demon's crest") == 0 ||
strcmp (ROMName, "ROCKMAN X") == 0 ||
strcmp (ROMName, "MEGAMAN X") == 0)
{
// CAPCOM's protect
// Banks 0x808000, 0x408000 are mirroring.
for (int c = 0; c < 8; c++)
Map [0x408 + c] = ROM - 0x8000;
}
if (strcmp (ROMName, "½°Ȩ̂߰нÀ") == 0 ||
strcmp (ROMName, "½°Ȩ̂߰нÀ 2") == 0 ||
strcmp (ROMName, "ZENKI TENCHIMEIDOU") == 0 ||
strcmp (ROMName, "GANBA LEAGUE") == 0)
{
SNESGameFixes.APU_OutPorts_ReturnValueFix = TRUE;
}
// HITOMI3
if (strcmp (ROMName, "HITOMI3") == 0)
{
Memory.SRAMSize = 1;
SRAMMask = Memory.SRAMSize ?
((1 << (Memory.SRAMSize + 3)) * 128) - 1 : 0;
}
if (strcmp (ROMName, "goemon 4") == 0)
SNESGameFixes.SRAMInitialValue = 0x00;
if (strcmp (ROMName, "PACHISLO ¹Ý·­³") == 0)
SNESGameFixes._0x213E_ReturnValue = 1;
if (strcmp (ROMName, "»Þ ϰ¼Þ¬Ý ijʲÃÞÝ") == 0)
SNESGameFixes.TouhaidenControllerFix = TRUE;
if (strcmp (ROMName, "DRAGON KNIGHT 4") == 0)
{
// Banks 70->7e, S-RAM
for (int c = 0; c < 0xe0; c++)
{
Map [c + 0x700] = (uint8 *) MAP_LOROM_SRAM;
BlockIsRAM [c + 0x700] = TRUE;
BlockIsROM [c + 0x700] = FALSE;
}
WriteProtectROM ();
}
if (strncmp (ROMName, "LETs PACHINKO(", 14) == 0)
{
(IAPUuncached.OneCycle) = 15;
if (!Settings.ForceNTSC && !Settings.ForcePAL)
{
Settings.PAL = FALSE;
Settings.FrameTime = Settings.FrameTimeNTSC;
ROMFramesPerSecond = 60;
}
}
if (strcmp (ROMName, "FURAI NO SIREN") == 0)
SNESGameFixes.SoundEnvelopeHeightReading2 = TRUE;
#if 0
if(strcmp (ROMName, "XBAND JAPANESE MODEM") == 0)
{
for (c = 0x200; c < 0x400; c += 16)
{
for (int i = c; i < c + 16; i++)
{
Map [i + 0x400] = Map [i + 0xc00] = &ROM[c * 0x1000];
MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = 8;
BlockIsRAM [i + 0x400] = BlockIsRAM [i + 0xc00] = TRUE;
BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = FALSE;
}
}
WriteProtectROM ();
}
#endif
#define RomPatch(adr,ov,nv) \
if (ROM [adr] == ov) \
ROM [adr] = nv
// Love Quest
if (strcmp (ROMName, "LOVE QUEST") == 0)
{
RomPatch (0x1385ec, 0xd0, 0xea);
RomPatch (0x1385ed, 0xb2, 0xea);
}
// Nangoku Syonen Papuwa Kun
if (strcmp (ROMName, "NANGOKUSYONEN PAPUWA") == 0)
RomPatch (0x1f0d1, 0xa0, 0x6b);
// Tetsuwan Atom
if (strcmp (ROMName, "Tetsuwan Atom") == 0)
{
RomPatch (0xe24c5, 0x90, 0xea);
RomPatch (0xe24c6, 0xf3, 0xea);
}
// Oda Nobunaga
if (strcmp (ROMName, "SFC ODA NOBUNAGA") == 0)
{
RomPatch (0x7497, 0x80, 0xea);
RomPatch (0x7498, 0xd5, 0xea);
}
// Super Batter Up
if (strcmp (ROMName, "Super Batter Up") == 0)
{
RomPatch (0x27ae0, 0xd0, 0xea);
RomPatch (0x27ae1, 0xfa, 0xea);
}
// Super Professional Baseball 2
if (strcmp (ROMName, "SUPER PRO. BASE BALL2") == 0)
{
RomPatch (0x1e4, 0x50, 0xea);
RomPatch (0x1e5, 0xfb, 0xea);
}
if (strncmp(ROMName, "FF MYSTIC QUEST",15) == 0)
{
if (Settings.CyclesPercentage == 100)
Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 120) / 100;
}
}
#define IPS_EOF 0x00454F46l
#define IPS_READ(mac_a,mac_b) \
if (ips_avail<mac_b) { \
char *temp_ptr=(char*)(mac_a);\
int tmp_b=mac_b; \
memcpy(temp_ptr,ips_data+ips_pos,ips_avail);ips_current+=ips_avail; tmp_b-=ips_avail; temp_ptr+=ips_avail;\
ips_avail=fread(ips_data,1,0x1000,patch_file);\
memcpy(temp_ptr,ips_data,tmp_b);ips_current+=tmp_b;ips_avail-=tmp_b;ips_pos=tmp_b; \
} else { \
memcpy(mac_a,ips_data+ips_pos,mac_b);ips_avail-=mac_b;ips_current+=mac_b;ips_pos+=mac_b; \
} \
if (!(scr_update&3)) psp_showProgressBar(ips_size-ips_current,ips_size);\
scr_update++;
void CMemory::CheckForIPSPatch (const char *rom_filename, bool8 header,uint32 &rom_size,const char *ips_ext) {
unsigned char bufferIPS[256];
char fname [256 + 1];
int scr_update;
FILE *patch_file;
uint8 *ips_data;
uint32 ips_size,ips_avail,ips_pos,ips_current;
uint32 Address;
int32 ofs;
uint16 PatchSize,rlen = 0;
char str[256];
char *p;
strcpy(fname,rom_filename);
p=strrchr(fname,'.');
if (!p) return;
strcpy(p,ips_ext);
patch_file = fopen(fname, "rb");
if (!patch_file) {
//no patch
return;
}
fseek(patch_file,0,SEEK_END);
ips_size=ftell(patch_file);
fseek(patch_file,0,SEEK_SET);
ips_data=(uint8*)malloc(0x1000); //small read buffer
if (!ips_data) {fclose (patch_file);return;}
ips_avail=0x1000;
ips_pos=0;
ips_current=0;
scr_update=0;
fread(ips_data,0x1000,1,patch_file);
//memcpy(fname,ips_data+ips_pos,5);ips_avail-=5;ips_current+=5;ips_pos+=5;
IPS_READ(fname,5)
if (strncmp (fname, "PATCH", 5) != 0) {
fclose(patch_file);
free(ips_data);
return;
}
sprintf(str, s9xTYL_msg[FILE_IPS_APPLYING], ips_ext + 1, ips_size >> 10);
msgBoxLines(str,0);
for (;;){
//memcpy(bufferIPS,ips_data+0x1000-ips_avail,3);ips_avail-=3;ips_current+=3;
IPS_READ(bufferIPS,3)
bufferIPS[3]=0;
if (!strcmp((char*)bufferIPS,"EOF")) {
//success
msgBoxLines(s9xTYL_msg[FILE_IPS_PATCHSUCCESS], 20);
break;
}
Address=(((uint32)(bufferIPS[0]))<<16)|(((uint32)(bufferIPS[1]))<<8)|(((uint32)(bufferIPS[2]))<<0);
//memcpy(bufferIPS,ips_pos,2);ips_pos+=2;
IPS_READ(bufferIPS,2)
PatchSize=(((uint32)(bufferIPS[0]))<<8)|(((uint32)(bufferIPS[1]))<<0);
if (!PatchSize) { //RLE compressed data
//memcpy(bufferIPS,ips_pos,2);ips_pos+=2;
IPS_READ(bufferIPS,2)
rlen=(((uint32)(bufferIPS[0]))<<8)|(((uint32)(bufferIPS[1]))<<0);
//memcpy(bufferIPS,ips_pos,1);ips_pos+=1;
IPS_READ(bufferIPS,1)
}
if (Address<rom_size) {
ofs=Address;
if (PatchSize) {
Address+=PatchSize;
if (rom_size<Address) {
rom_size=Address;
// printf("Extending\n");
}
// printf("Regular patch %04X %d\n",Address,PatchSize);
while (PatchSize--) {
//memcpy(bufferIPS,ips_pos,1);ips_pos+=1;
IPS_READ(bufferIPS,1)
ROM[ofs]=bufferIPS[0];
ofs++;
}
} else {
Address+=rlen;
if (rom_size<Address) {
rom_size=Address;
// printf("Extending\n");
msgBoxLines(s9xTYL_msg[EXTENDING], 30);
}
// printf("RLE patcht %04X %d %d\n",Address,rlen,Byte);
memset(ROM+ofs,bufferIPS[0],rlen);
ofs+=rlen;
}
} else {
sprintf(str, s9xTYL_msg[EXTENDING_TARGET], rom_size, Address);
msgBoxLines(str,30);
memset(ROM+rom_size,0,Address-rom_size);
rom_size=Address;
}
//printf("File pos %d\n",ftell(fips));
}
free(ips_data);
fclose(patch_file);
}
/*#undef INLINE
#define INLINE
#include "getset.h"*/
#if 0
#include "dsp1.h"
uint8 MapGetBytePPU(uint32 Address)
{
if (!CPU.InDMA)
CPU.Cycles += ONE_CYCLE;
return (S9xGetPPU (Address & 0xFFFF));
}
uint16 MapGetWordPPU(uint32 Address)
{
if (!CPU.InDMA)
CPU.Cycles += TWO_CYCLES;
return (S9xGetPPU (Address & 0xffff) |
(S9xGetPPU ((Address + 1) & 0xffff) << 8));
}
uint16 MapGetWordCPU(uint32 Address)
{
return (S9xGetCPU (Address & 0xffff) |
(S9xGetCPU ((Address + 1) & 0xffff) << 8));
}
uint16 MapGetWordDSP(uint32 Address)
{
return (S9xGetDSP (Address & 0xffff) |
(S9xGetDSP ((Address + 1) & 0xffff) << 8));
}
uint8 MapGetByteLOROM_SRAM(uint32 Address)
{
return (*(SRAM + ((((Address&0xFF0000)>>1) |(Address&0x7FFF)) &Memory.SRAMMask)));
}
uint16 MapGetWordLOROM_SRAM(uint32 Address)
{
if(Memory.SRAMMask>=MEMMAP_MASK){
return READ_WORD(SRAM + ((((Address&0xFF0000)>>1) |(Address&0x7FFF)) &Memory.SRAMMask));
} else {
/* no READ_WORD here, since if Memory.SRAMMask=0x7ff
* then the high byte doesn't follow the low byte. */
return
(*(SRAM + ((((Address&0xFF0000)>>1) |(Address&0x7FFF)) &Memory.SRAMMask)))|
((*(SRAM + (((((Address+1)&0xFF0000)>>1) |((Address+1)&0x7FFF)) &Memory.SRAMMask)))<<8);
}
}
uint8 MapGetByteHIROM_SRAM(uint32 Address)
{
return (*(SRAM + (((Address & 0x7fff) - 0x6000 +
((Address & 0xf0000) >> 3)) & Memory.SRAMMask)));
}
uint16 MapGetWordHIROM_SRAM(uint32 Address)
{
if(Memory.SRAMMask>=MEMMAP_MASK){
return READ_WORD(SRAM +
(((Address & 0x7fff) - 0x6000 +
((Address & 0xf0000) >> 3)) & Memory.SRAMMask));
} else {
/* no READ_WORD here, since if Memory.SRAMMask=0x7ff
* then the high byte doesn't follow the low byte. */
return (*(SRAM +
(((Address & 0x7fff) - 0x6000 +
((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) |
(*(SRAM +
((((Address + 1) & 0x7fff) - 0x6000 +
(((Address + 1) & 0xf0000) >> 3)) & Memory.SRAMMask)) << 8));
}
}
uint8 MapGetByteBWRAM(uint32 Address)
{
return (*(BWRAM + ((Address & 0x7fff) - 0x6000)));
}
uint16 MapGetWordBWRAM(uint32 Address)
{
return (*(BWRAM + ((Address & 0x7fff) - 0x6000)) |
(*(BWRAM + (((Address + 1) & 0x7fff) - 0x6000)) << 8));
}
uint8 MapGetByteC4(uint32 Address)
{
return (S9xGetC4 (Address & 0xffff));
}
uint16 MapGetWordC4(uint32 Address)
{
return (S9xGetC4 (Address & 0xffff) |
(S9xGetC4 ((Address + 1) & 0xffff) << 8));
}
uint8 MapGetByteNONE(uint32 Address)
{
return ((Address >> 8) & 0xff);
}
uint16 MapGetWordNONE(uint32 Address)
{
return (((Address >> 8) | (Address & 0xff00)) & 0xffff);
}
void MapSetBytePPU (uint8 Byte, uint32 Address)
{
if (!CPU.InDMA)
CPU.Cycles += ONE_CYCLE;
S9xSetPPU (Byte, Address & 0xffff);
}
void MapSetWordPPU (uint16 Word, uint32 Address)
{
S9xSetPPU ((uint8) Word, Address & 0xffff);
S9xSetPPU (Word >> 8, (Address & 0xffff) + 1);
}
void MapSetByteCPU (uint8 Byte, uint32 Address)
{
S9xSetCPU (Byte, Address & 0xffff);
}
void MapSetWordCPU (uint16 Word, uint32 Address)
{
S9xSetCPU ((uint8) Word, (Address & 0xffff));
S9xSetCPU (Word >> 8, (Address & 0xffff) + 1);
}
void MapSetWordDSP (uint16 Word, uint32 Address)
{
S9xSetDSP ((uint8) Word, (Address & 0xffff));
S9xSetDSP (Word >> 8, (Address & 0xffff) + 1);
}
void MapSetByteLOROM_SRAM (uint8 Byte, uint32 Address)
{
if (Memory.SRAMMask)
{
*(SRAM + ((((Address&0xFF0000)>>1)|(Address&0x7FFF))& Memory.SRAMMask))=Byte;
CPU.SRAMModified = TRUE;
}
}
void MapSetWordLOROM_SRAM (uint16 Word, uint32 Address)
{
if (Memory.SRAMMask) {
if(Memory.SRAMMask>=MEMMAP_MASK){
WRITE_WORD(SRAM + ((((Address&0xFF0000)>>1)|(Address&0x7FFF))&Memory.SRAMMask), Word);
} else {
/* no WRITE_WORD here, since if Memory.SRAMMask=0x7ff
* then the high byte doesn't follow the low byte. */
*(SRAM + ((((Address&0xFF0000)>>1)|(Address&0x7FFF))& Memory.SRAMMask)) = (uint8) Word;
*(SRAM + (((((Address+1)&0xFF0000)>>1)|((Address+1)&0x7FFF))& Memory.SRAMMask)) = Word >> 8;
}
CPU.SRAMModified = TRUE;
}
}
void MapSetByteHIROM_SRAM (uint8 Byte, uint32 Address)
{
if (Memory.SRAMMask)
{
*(SRAM + (((Address & 0x7fff) - 0x6000 +
((Address & 0xf0000) >> 3)) & Memory.SRAMMask)) = Byte;
CPU.SRAMModified = TRUE;
}
}
void MapSetWordHIROM_SRAM (uint16 Word, uint32 Address)
{
if (Memory.SRAMMask)
{
if(Memory.SRAMMask>=MEMMAP_MASK){
WRITE_WORD(SRAM +
(((Address & 0x7fff) - 0x6000 +
((Address & 0xf0000) >> 3) & Memory.SRAMMask)), Word);
} else {
/* no WRITE_WORD here, since if Memory.SRAMMask=0x7ff
* then the high byte doesn't follow the low byte. */
*(SRAM +
(((Address & 0x7fff) - 0x6000 +
((Address & 0xf0000) >> 3) & Memory.SRAMMask))) = (uint8) Word;
*(SRAM +
((((Address + 1) & 0x7fff) - 0x6000 +
(((Address + 1) & 0xf0000) >> 3) & Memory.SRAMMask))) = (uint8) (Word >> 8);
}
CPU.SRAMModified = TRUE;
}
}
void MapSetByteBWRAM (uint8 Byte, uint32 Address)
{
*(BWRAM + ((Address & 0x7fff) - 0x6000)) = Byte;
CPU.SRAMModified = TRUE;
}
void MapSetWordBWRAM (uint16 Word, uint32 Address)
{
*(BWRAM + ((Address & 0x7fff) - 0x6000)) = (uint8) Word;
*(BWRAM + (((Address + 1) & 0x7fff) - 0x6000)) = (uint8) (Word >> 8);
CPU.SRAMModified = TRUE;
}
void MapSetByteSA1RAM (uint8 Byte, uint32 Address)
{
*(SRAM + (Address & 0xffff)) = Byte;
SA1.Executing = !SA1.Waiting;
}
void MapSetWordSA1RAM (uint16 Word, uint32 Address)
{
*(SRAM + (Address & 0xffff)) = (uint8) Word;
*(SRAM + ((Address + 1) & 0xffff)) = (uint8) (Word >> 8);
SA1.Executing = !SA1.Waiting;
}
void MapSetWordC4 (uint16 Word, uint32 Address)
{
S9xSetC4 (Word & 0xff, Address & 0xffff);
S9xSetC4 ((uint8) (Word >> 8), (Address + 1) & 0xffff);
}
void MapSetByteNONE (uint8 Byte, uint32 Address)
{}
#endif
void InitNewMap()
{
#if 0
int block;
for(int i=0;i<MEMMAP_NUM_BLOCKS;i++)
{
block=i;
uint8 *GetAddress = Map [block];
GetByteMap[i].BlockIsRAM = Memory.BlockIsRAM [block];
GetByteMap[i].BlockIsROM = Memory.BlockIsROM [block];
GetWordMap[i].BlockIsRAM = Memory.BlockIsRAM [block];
GetWordMap[i].BlockIsROM = Memory.BlockIsROM [block];
SetByteMap[i].BlockIsRAM = Memory.BlockIsRAM [block];
SetByteMap[i].BlockIsROM = Memory.BlockIsROM [block];
SetWordMap[i].BlockIsRAM = Memory.BlockIsRAM [block];
SetWordMap[i].BlockIsROM = Memory.BlockIsROM [block];
if (GetAddress >= (uint8 *) CMemory::MAP_LAST)
{
GetByteMap[i].MemorySpeed = Memory.MemorySpeed [block];
// GetByteMap[i].MemorySpeedx2 = Memory.MemorySpeed [block]<<1;
GetByteMap[i].func=0;
GetWordMap[i].MemorySpeed = Memory.MemorySpeed [block]<<1;
GetWordMap[i].func=0;
}
else
switch ((int) GetAddress)
{
case CMemory::MAP_PPU:
GetByteMap[i].func=(int)MapGetBytePPU;
GetByteMap[i].MemorySpeed=0;
GetWordMap[i].func=(int)MapGetWordPPU;
GetWordMap[i].MemorySpeed=0;
break;
case CMemory::MAP_CPU:
GetByteMap[i].func=(int)S9xGetCPU;
GetByteMap[i].MemorySpeed=ONE_CYCLE;
GetWordMap[i].func=(int)MapGetWordCPU;
GetWordMap[i].MemorySpeed=TWO_CYCLES;
break;
case CMemory::MAP_DSP:
GetByteMap[i].func=(int)DSP1GetByte;
GetByteMap[i].MemorySpeed=SLOW_ONE_CYCLE;
GetWordMap[i].func=(int)MapGetWordDSP;
GetWordMap[i].MemorySpeed=SLOW_ONE_CYCLE * 2;
break;
case CMemory::MAP_SA1RAM:
case CMemory::MAP_LOROM_SRAM:
GetByteMap[i].func=(int)MapGetByteLOROM_SRAM;
GetByteMap[i].MemorySpeed=SLOW_ONE_CYCLE;
GetWordMap[i].func=(int)MapGetWordLOROM_SRAM;
GetWordMap[i].MemorySpeed=SLOW_ONE_CYCLE * 2;
break;
case CMemory::MAP_HIROM_SRAM:
GetByteMap[i].func=(int)MapGetByteHIROM_SRAM;
GetByteMap[i].MemorySpeed=SLOW_ONE_CYCLE;
GetWordMap[i].func=(int)MapGetWordHIROM_SRAM;
GetWordMap[i].MemorySpeed=SLOW_ONE_CYCLE * 2;
break;
case CMemory::MAP_DEBUG:
case CMemory::MAP_BWRAM:
GetByteMap[i].func=(int)MapGetByteBWRAM;
GetByteMap[i].MemorySpeed=SLOW_ONE_CYCLE;
GetWordMap[i].func=(int)MapGetWordBWRAM;
GetWordMap[i].MemorySpeed=SLOW_ONE_CYCLE * 2;
break;
case CMemory::MAP_C4:
GetByteMap[i].func=(int)MapGetByteC4;
GetByteMap[i].MemorySpeed=0;
GetWordMap[i].func=(int)MapGetWordC4;
GetWordMap[i].MemorySpeed=0;
break;
default:
case CMemory::MAP_NONE:
GetByteMap[i].func=(int)MapGetByteNONE;
GetByteMap[i].MemorySpeed=SLOW_ONE_CYCLE;
GetWordMap[i].func=(int)MapGetWordNONE;
GetWordMap[i].MemorySpeed=SLOW_ONE_CYCLE * 2;
}
block=i;
uint8 *SetAddress = Memory.WriteMap [block];
if (SetAddress >= (uint8 *) CMemory::MAP_LAST)
{
SetByteMap[i].MemorySpeed = Memory.MemorySpeed [block];
// SetByteMap[i].MemorySpeedx2 = Memory.MemorySpeed [block]<<1;
SetByteMap[i].func=0;
SetWordMap[i].MemorySpeed = Memory.MemorySpeed [block]<<1;
SetWordMap[i].func=0;
}
else
switch ((int) SetAddress)
{
case CMemory::MAP_PPU:
SetByteMap[i].func=(int)MapSetBytePPU;
SetByteMap[i].MemorySpeed=0;
SetWordMap[i].func=(int)MapSetWordPPU;
SetWordMap[i].MemorySpeed=TWO_CYCLES;
break;
case CMemory::MAP_CPU:
SetByteMap[i].func=(int)MapSetByteCPU;//S9xSetCPU;
SetByteMap[i].MemorySpeed=ONE_CYCLE;
SetWordMap[i].func=(int)MapSetWordCPU;
SetWordMap[i].MemorySpeed=TWO_CYCLES;
break;
case CMemory::MAP_DSP:
SetByteMap[i].func=(int)DSP1SetByte;
SetByteMap[i].MemorySpeed=SLOW_ONE_CYCLE;
SetWordMap[i].func=(int)MapSetWordDSP;
SetWordMap[i].MemorySpeed=SLOW_ONE_CYCLE * 2;
break;
case CMemory::MAP_LOROM_SRAM:
SetByteMap[i].func=(int)MapSetByteLOROM_SRAM;
SetByteMap[i].MemorySpeed=SLOW_ONE_CYCLE;
SetWordMap[i].func=(int)MapSetWordLOROM_SRAM;
SetWordMap[i].MemorySpeed=SLOW_ONE_CYCLE * 2;
break;
case CMemory::MAP_HIROM_SRAM:
SetByteMap[i].func=(int)MapSetByteHIROM_SRAM;
SetByteMap[i].MemorySpeed=SLOW_ONE_CYCLE;
SetWordMap[i].func=(int)MapSetWordHIROM_SRAM;
SetWordMap[i].MemorySpeed=SLOW_ONE_CYCLE * 2;
break;
case CMemory::MAP_BWRAM:
SetByteMap[i].func=(int)MapSetByteBWRAM;
SetByteMap[i].MemorySpeed=SLOW_ONE_CYCLE;
SetWordMap[i].func=(int)MapSetWordBWRAM;
SetWordMap[i].MemorySpeed=SLOW_ONE_CYCLE * 2;
break;
case CMemory::MAP_DEBUG:
case CMemory::MAP_SA1RAM:
SetByteMap[i].func=(int)MapSetByteSA1RAM;
SetByteMap[i].MemorySpeed=SLOW_ONE_CYCLE;
SetWordMap[i].func=(int)MapSetWordSA1RAM;
SetWordMap[i].MemorySpeed=SLOW_ONE_CYCLE;
break;
case CMemory::MAP_C4:
SetByteMap[i].func=(int)S9xSetC4;
SetByteMap[i].MemorySpeed=0;
SetWordMap[i].func=(int)MapSetWordC4;
SetWordMap[i].MemorySpeed=0;
break;
default:
case CMemory::MAP_NONE:
SetByteMap[i].func=(int)MapSetByteNONE;
SetByteMap[i].MemorySpeed=SLOW_ONE_CYCLE;
SetWordMap[i].func=(int)MapSetByteNONE;
SetWordMap[i].MemorySpeed=SLOW_ONE_CYCLE*2;
break;
}
}
#endif
}