diff --git a/bsx.cpp b/bsx.cpp
index c317bd26..2b4454e3 100644
--- a/bsx.cpp
+++ b/bsx.cpp
@@ -199,7 +199,7 @@
//#define BSX_DEBUG
#define BIOS_SIZE 0x100000
-#define FLASH_SIZE 0x200000
+#define FLASH_SIZE 0x100000
#define PSRAM_SIZE 0x80000
#define Map Memory.Map
@@ -231,7 +231,7 @@ static const uint8 flashcard[20] =
{
0x4D, 0x00, 0x50, 0x00, // vendor id
0x00, 0x00, // ?
- 0x2B, 0x00, // 2MB Flash (1MB = 0x2A)
+ 0x1A, 0x00, // 2MB Flash (1MB = 0x2A)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
@@ -417,13 +417,22 @@ static void map_psram_mirror_sub (uint32 bank)
{
for (c = 0; c < 0x100; c += 16)
{
- for (i = c; i < c + 8; i++)
- Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE];
+ if ((bank & 0x7F) >= 0x40)
+ {
+ for (i = c; i < c + 8; i++)
+ Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE];
+
+ for (i = c; i < c + 8; i++)
+ {
+ BlockIsRAM[i + bank] = TRUE;
+ BlockIsROM[i + bank] = FALSE;
+ }
+ }
for (i = c + 8; i < c + 16; i++)
Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE] - 0x8000;
- for (i = c; i < c + 16; i++)
+ for (i = c + 8; i < c + 16; i++)
{
BlockIsRAM[i + bank] = TRUE;
BlockIsROM[i + bank] = FALSE;
@@ -432,42 +441,126 @@ static void map_psram_mirror_sub (uint32 bank)
}
}
-static void BSX_Map_PSRAM (void)
+static void BSX_Map_PSRAM(void)
{
- int c;
+ int c, i;
- // Banks 70->77:0000-FFFF
- // FIXME: could be toggled by $03
- for (c = 0; c < 0x80; c++)
+ if (!BSX.MMC[0x02])
{
- Map[c + 0x700] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE];
- BlockIsRAM[c + 0x700] = TRUE;
- BlockIsROM[c + 0x700] = FALSE;
- }
+ //LoROM Mode
+ if (!BSX.MMC[0x05] && !BSX.MMC[0x06])
+ {
+ //Map PSRAM to 00-0F/80-8F
+ if (BSX.MMC[0x03])
+ map_psram_mirror_sub(0x00);
- // Banks 20->3F:6000-7FFF mirrors 70->77:6000-7FFF
- for (c = 0x200; c < 0x400; c += 16)
+ if (BSX.MMC[0x04])
+ map_psram_mirror_sub(0x80);
+ }
+ else if (BSX.MMC[0x05] && !BSX.MMC[0x06])
+ {
+ //Map PSRAM to 20-2F/A0-AF
+ if (BSX.MMC[0x03])
+ map_psram_mirror_sub(0x20);
+
+ if (BSX.MMC[0x04])
+ map_psram_mirror_sub(0xA0);
+ }
+ else if (!BSX.MMC[0x05] && BSX.MMC[0x06])
+ {
+ //Map PSRAM to 40-4F/C0-CF
+ if (BSX.MMC[0x03])
+ map_psram_mirror_sub(0x40);
+
+ if (BSX.MMC[0x04])
+ map_psram_mirror_sub(0xC0);
+ }
+ else
+ {
+ //Map PSRAM to 60-6F/E0-EF
+ if (BSX.MMC[0x03])
+ map_psram_mirror_sub(0x60);
+
+ if (BSX.MMC[0x04])
+ map_psram_mirror_sub(0xE0);
+ }
+
+ //Map PSRAM to 70-7D/F0-FF
+ if (BSX.MMC[0x03])
+ map_psram_mirror_sub(0x70);
+
+ if (BSX.MMC[0x04])
+ map_psram_mirror_sub(0xF0);
+ }
+ else
{
- Map[c + 6] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE];
- Map[c + 7] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE];
- BlockIsRAM[c + 6] = TRUE;
- BlockIsRAM[c + 7] = TRUE;
- BlockIsROM[c + 6] = FALSE;
- BlockIsROM[c + 7] = FALSE;
+ //HiROM Mode
+ if (!BSX.MMC[0x05] && !BSX.MMC[0x06])
+ {
+ //Map PSRAM to 40-47/C0-C7
+ if (BSX.MMC[0x03])
+ map_psram_mirror_sub(0x40);
+
+ if (BSX.MMC[0x04])
+ map_psram_mirror_sub(0xC0);
+
+ }
+ else if (BSX.MMC[0x05] && !BSX.MMC[0x06])
+ {
+ //Map PSRAM to 50-57/D0-D7
+ if (BSX.MMC[0x03])
+ map_psram_mirror_sub(0x50);
+
+ if (BSX.MMC[0x04])
+ map_psram_mirror_sub(0xD0);
+ }
+ else if (!BSX.MMC[0x05] && BSX.MMC[0x06])
+ {
+ //Map PSRAM to 60-67/E0-E7
+ if (BSX.MMC[0x03])
+ map_psram_mirror_sub(0x60);
+
+ if (BSX.MMC[0x04])
+ map_psram_mirror_sub(0xE0);
+ }
+ else
+ {
+ //Map PSRAM to 70-77/F0-F7
+ if (BSX.MMC[0x03])
+ map_psram_mirror_sub(0x70);
+
+ if (BSX.MMC[0x04])
+ map_psram_mirror_sub(0xF0);
+ }
+
+ if (BSX.MMC[0x03])
+ {
+ //Map PSRAM to 20->3F:6000-7FFF
+ for (c = 0x200; c < 0x400; c += 16)
+ {
+ Map[c + 6] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE];
+ Map[c + 7] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE];
+ BlockIsRAM[c + 6] = TRUE;
+ BlockIsRAM[c + 7] = TRUE;
+ BlockIsROM[c + 6] = FALSE;
+ BlockIsROM[c + 7] = FALSE;
+ }
+ }
+
+ if (BSX.MMC[0x04])
+ {
+ //Map PSRAM to A0->BF:6000-7FFF
+ for (c = 0xA00; c < 0xC00; c += 16)
+ {
+ Map[c + 6] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE];
+ Map[c + 7] = &PSRAM[((c & 0x70) << 12) % PSRAM_SIZE];
+ BlockIsRAM[c + 6] = TRUE;
+ BlockIsRAM[c + 7] = TRUE;
+ BlockIsROM[c + 6] = FALSE;
+ BlockIsROM[c + 7] = FALSE;
+ }
+ }
}
-
- if (!BSX.MMC[0x05])
- // Banks 40->4F:0000-FFFF mirrors 70->77:0000-7FFF
- map_psram_mirror_sub(0x40);
-
- if (!BSX.MMC[0x06])
- // Banks 50->5F:0000-FFFF mirrors 70->77:0000-7FFF
- map_psram_mirror_sub(0x50);
-
- // FIXME
- if (!BSX.MMC[0x03])
- // Banks 60->6F:0000-FFFF mirrors 70->77:0000-7FFF (?)
- map_psram_mirror_sub(0x60);
}
static void BSX_Map_BIOS (void)
@@ -562,28 +655,8 @@ static void BSX_Map (void)
memcpy(BSX.prevMMC, BSX.MMC, sizeof(BSX.MMC));
- // Do a quick bank change
- if (BSX.dirty2 && !BSX.dirty)
- {
- BSX_Map_Dirty();
- BSX_Map_BIOS();
-
- BSX.dirty2 = FALSE;
-
- Memory.map_WriteProtectROM();
- return;
- }
-
- if (BSX.MMC[0x01])
- {
- MapROM = PSRAM;
- FlashSize = PSRAM_SIZE;
- }
- else
- {
- MapROM = FlashROM;
- FlashSize = FLASH_SIZE;
- }
+ MapROM = FlashROM;
+ FlashSize = FLASH_SIZE;
BSX_Map_SNES();
@@ -592,12 +665,12 @@ static void BSX_Map (void)
else
BSX_Map_LoROM();
+ BSX_Map_FlashIO();
BSX_Map_PSRAM();
BSX_Map_SRAM();
BSX_Map_RAM();
BSX_Map_BIOS();
- BSX_Map_FlashIO();
BSX_Map_MMC();
// Monitor new register changes
@@ -607,30 +680,24 @@ static void BSX_Map (void)
Memory.map_WriteProtectROM();
}
-static uint8 BSX_Get_Bypass_FlashIO (uint16 offset)
+static uint8 BSX_Get_Bypass_FlashIO (uint32 offset)
{
+ MapROM = FlashROM = Memory.ROM + Multi.cartOffsetB;
+
if (BSX.MMC[0x02])
- return (MapROM[offset]);
+ return (MapROM[offset & 0x0FFFFF]);
else
- {
- if (offset < 0x8000)
- return (MapROM[offset]);
- else
- return (MapROM[offset - 0x8000]);
- }
+ return (MapROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)]);
}
-static void BSX_Set_Bypass_FlashIO (uint16 offset, uint8 byte)
+static void BSX_Set_Bypass_FlashIO (uint32 offset, uint8 byte)
{
+ MapROM = FlashROM = Memory.ROM + Multi.cartOffsetB;
+
if (BSX.MMC[0x02])
- MapROM[offset] = byte;
+ MapROM[offset & 0x0FFFFF] = MapROM[offset & 0x0FFFFF] & byte;
else
- {
- if (offset < 0x8000)
- MapROM[offset] = byte;
- else
- MapROM[offset - 0x8000] = byte;
- }
+ MapROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)] = MapROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)] & byte;
}
uint8 S9xGetBSX (uint32 address)
@@ -640,43 +707,57 @@ uint8 S9xGetBSX (uint32 address)
uint8 t = 0;
// MMC
- if ((bank >= 0x01 && bank <= 0x0E) && (offset == 0x5000))
+ if ((bank >= 0x01 && bank <= 0x0E))
return (BSX.MMC[bank]);
// Flash IO
- if (bank == 0xC0)
+ if (bank >= 0xC0)
{
// default: read-through mode
- t = BSX_Get_Bypass_FlashIO(offset);
+ t = BSX_Get_Bypass_FlashIO(address);
// note: may be more registers, purposes unknown
switch (offset)
{
- case 0x0002:
- if (BSX.flash_enable)
- t = 0x80; // status register?
- break;
+ case 0x0002:
+ case 0x8002:
+ if (BSX.flash_bsr)
+ t = 0xC0; // Page Status Register
+ break;
- case 0x5555:
- if (BSX.flash_enable)
- t = 0x80; // ???
- break;
+ case 0x0004:
+ case 0x8004:
+ if (BSX.flash_gsr)
+ t = 0x82; // Global Status Register
+ break;
- case 0xFF00:
- case 0xFF02:
- case 0xFF04:
- case 0xFF06:
- case 0xFF08:
- case 0xFF0A:
- case 0xFF0C:
- case 0xFF0E:
- case 0xFF10:
- case 0xFF12:
- // return flash vendor information
- if (BSX.read_enable)
- t = flashcard[offset - 0xFF00];
- break;
+ case 0x5555:
+ if (BSX.flash_enable)
+ t = 0x80; // ???
+ break;
+
+ case 0xFF00:
+ case 0xFF02:
+ case 0xFF04:
+ case 0xFF06:
+ case 0xFF08:
+ case 0xFF0A:
+ case 0xFF0C:
+ case 0xFF0E:
+ case 0xFF10:
+ case 0xFF12:
+ // return flash vendor information
+ if (BSX.read_enable)
+ t = flashcard[offset - 0xFF00];
+ break;
}
+
+ if (BSX.flash_csr)
+ {
+ t = 0x80; // Compatible Status Register
+ BSX.flash_csr = false;
+ }
+
}
return (t);
@@ -688,115 +769,126 @@ void S9xSetBSX (uint8 byte, uint32 address)
uint16 offset = address & 0xFFFF;
// MMC
- if ((bank >= 0x01 && bank <= 0x0E) && (offset == 0x5000))
+ if ((bank >= 0x01 && bank <= 0x0E))
{
- switch (bank)
- {
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x09:
- case 0x0A:
- case 0x0B:
- case 0x0C:
- case 0x0D:
- if (BSX.MMC[bank] != byte)
- {
- BSX.MMC[bank] = byte;
- BSX.dirty = TRUE;
- }
- break;
-
- case 0x07:
- case 0x08:
- if (BSX.MMC[bank] != byte)
- {
- BSX.MMC[bank] = byte;
- BSX.dirty2 = TRUE;
- }
- break;
-
- case 0x0E:
- BSX.MMC[bank] = byte;
- if (byte && (BSX.dirty || BSX.dirty2))
- BSX_Map();
- break;
- }
+ BSX.MMC[bank] = byte;
+ if (bank == 0x0E)
+ BSX_Map();
}
// Flash IO
- if (bank == 0xC0)
+ if (bank >= 0xC0)
{
- BSX.old_write = BSX.new_write;
- BSX.new_write = address;
-
- // ???: double writes to the desired address will bypass
- // flash registers
- if (BSX.old_write == BSX.new_write && BSX.write_enable)
+ // Write to Flash
+ if (BSX.write_enable)
{
- BSX_Set_Bypass_FlashIO(offset, byte);
+ BSX_Set_Bypass_FlashIO(address, byte);
+ //MapROM[address & 0x3FFFFF] = byte;
+ BSX.write_enable = false;
return;
}
- // flash command handling
- // note: incomplete
- switch (offset)
- {
- case 0x0000:
- BSX.flash_command <<= 8;
- BSX.flash_command |= byte;
- if ((BSX.flash_command & 0xFFFF) == 0x38D0)
- {
- // retrieve information about the flash card
- BSX.flash_enable = TRUE;
- BSX.read_enable = TRUE;
- }
- break;
+ // Flash Command Handling
+ if (BSX.MMC[0xC]) {
+ //Memory Pack Type 1 & 3 & 4
+ BSX.flash_command <<= 8;
+ BSX.flash_command |= byte;
- case 0x2AAA:
- BSX.flash_command <<= 8;
- BSX.flash_command |= byte;
- break;
+ switch (BSX.flash_command & 0xFF)
+ {
+ case 0x00:
+ case 0xFF:
+ //Reset to normal
+ BSX.flash_enable = false;
+ BSX.flash_bsr = false;
+ BSX.flash_csr = false;
+ BSX.flash_gsr = false;
+ BSX.read_enable = false;
+ BSX.write_enable = false;
+ BSX.flash_cmd_done = true;
+ break;
- case 0x5555:
- BSX.flash_command <<= 8;
- BSX.flash_command |= byte;
+ case 0x10:
+ case 0x40:
+ //Write Byte
+ BSX.flash_enable = false;
+ BSX.flash_bsr = false;
+ BSX.flash_csr = true;
+ BSX.flash_gsr = false;
+ BSX.read_enable = false;
+ BSX.write_enable = true;
+ BSX.flash_cmd_done = true;
+ break;
- switch (BSX.flash_command & 0xFFFFFF)
- {
- case 0xAA55F0:
- // turn off flash i/o
- BSX.flash_enable = FALSE;
- BSX.write_enable = FALSE;
- BSX.read_enable = FALSE;
- break;
+ case 0x50:
+ //Clear Status Register
+ BSX.flash_enable = false;
+ BSX.flash_bsr = false;
+ BSX.flash_csr = false;
+ BSX.flash_gsr = false;
+ BSX.flash_cmd_done = true;
+ break;
- case 0xAA55A0:
- // enable writing to flash
- BSX.old_write = 0;
- BSX.new_write = 0;
- BSX.flash_enable = TRUE;
- BSX.write_enable = TRUE;
- BSX_Map();
- break;
+ case 0x70:
+ //Read CSR
+ BSX.flash_enable = false;
+ BSX.flash_bsr = false;
+ BSX.flash_csr = true;
+ BSX.flash_gsr = false;
+ BSX.read_enable = false;
+ BSX.write_enable = false;
+ BSX.flash_cmd_done = true;
+ break;
- case 0xAA5570:
- // turn on write-protection
- BSX.write_enable = FALSE;
- BSX_Map();
- break;
+ case 0x71:
+ //Read Extended Status Registers (Page and Global)
+ BSX.flash_enable = false;
+ BSX.flash_bsr = true;
+ BSX.flash_csr = false;
+ BSX.flash_gsr = true;
+ BSX.read_enable = false;
+ BSX.write_enable = false;
+ BSX.flash_cmd_done = true;
+ break;
- case 0xAA5580:
- case 0xAA5510:
- // ???
- break;
+ case 0x75:
+ //Show Page Buffer / Vendor Info
+ BSX.flash_csr = false;
+ BSX.read_enable = true;
+ BSX.flash_cmd_done = true;
+ break;
- }
+ case 0xD0:
+ //DO COMMAND
+ switch (BSX.flash_command & 0xFFFF)
+ {
+ case 0x20D0: //Block Erase
+ uint32 x;
+ for (x = 0; x < 0x10000; x++) {
+ //BSX_Set_Bypass_FlashIO(((address & 0xFF0000) + x), 0xFF);
+ if (BSX.MMC[0x02])
+ MapROM[(address & 0x0F0000) + x] = 0xFF;
+ else
+ MapROM[((address & 0x1E0000) >> 1) + x] = 0xFF;
+ }
+ break;
- break;
+ case 0xA7D0: //Chip Erase (ONLY IN TYPE 1 AND 4)
+ if ((flashcard[6] & 0xF0) == 0x10 || (flashcard[6] & 0xF0) == 0x40)
+ {
+ uint32 x;
+ for (x = 0; x < FLASH_SIZE; x++) {
+ //BSX_Set_Bypass_FlashIO(x, 0xFF);
+ MapROM[x] = 0xFF;
+ }
+ }
+ break;
+
+ case 0x38D0: //Flashcart Reset
+ break;
+ }
+ break;
+ }
}
}
}
@@ -1082,7 +1174,7 @@ void S9xInitBSX (void)
uint8 *header = r1 ? Memory.ROM + 0x7FC0 : Memory.ROM + 0xFFC0;
FlashMode = (header[0x18] & 0xEF) == 0x20 ? FALSE : TRUE;
- FlashSize = (header[0x19] & 0x20) ? PSRAM_SIZE : FLASH_SIZE;
+ FlashSize = FLASH_SIZE;
#ifdef BSX_DEBUG
for (int i = 0; i <= 0x1F; i++)
@@ -1145,32 +1237,11 @@ void S9xResetBSX (void)
memset(BSX.output, 0, sizeof(BSX.output));
// starting from the bios
- if (BSX.bootup)
- BSX.MMC[0x07] = BSX.MMC[0x08] = 0x80;
- else
- {
- BSX.MMC[0x02] = FlashMode ? 0x80: 0;
+ BSX.MMC[0x02] = BSX.MMC[0x03] = BSX.MMC[0x05] = BSX.MMC[0x06] = 0x80;
+ BSX.MMC[0x09] = BSX.MMC[0x0B] = 0x80;
- // per bios: run from psram or flash card
- if (FlashSize == PSRAM_SIZE)
- {
- memcpy(PSRAM, FlashROM, PSRAM_SIZE);
-
- BSX.MMC[0x01] = 0x80;
- BSX.MMC[0x03] = 0x80;
- BSX.MMC[0x04] = 0x80;
- BSX.MMC[0x0C] = 0x80;
- BSX.MMC[0x0D] = 0x80;
- }
- else
- {
- BSX.MMC[0x03] = 0x80;
- BSX.MMC[0x05] = 0x80;
- BSX.MMC[0x06] = 0x80;
- }
-
- BSX.MMC[0x0E] = 0x80;
- }
+ BSX.MMC[0x07] = BSX.MMC[0x08] = 0x80;
+ BSX.MMC[0x0E] = 0x80;
BSX_Map();
}
diff --git a/bsx.h b/bsx.h
index 5d5ea03d..ac5a2906 100644
--- a/bsx.h
+++ b/bsx.h
@@ -208,6 +208,11 @@ struct SBSX
uint8 MMC[16];
uint8 prevMMC[16];
uint8 test2192[32];
+
+ bool flash_csr;
+ bool flash_gsr;
+ bool flash_bsr;
+ bool flash_cmd_done;
};
extern struct SBSX BSX;
diff --git a/gtk/configure.ac b/gtk/configure.ac
index e3bab4eb..50f204f3 100644
--- a/gtk/configure.ac
+++ b/gtk/configure.ac
@@ -331,9 +331,9 @@ if test no != "$with_system_zip" && test yes = "$with_zlib" ; then
LIBS="$LIBS $SYSTEM_ZIP_LIBS"
],[
if test check = "$with_system_zip"; then
- AC_MSG_WARN(Cannot find SYSTEM_ZIP)
+ AC_MSG_WARN(Cannot find system minizip library)
else
- AC_MSG_ERROR(--with-system-zip given but cannot find proper zlib)
+ AC_MSG_ERROR(--with-system-zip given but cannot find system minizip library)
fi
])
fi
diff --git a/gtk/src/gtk_file.cpp b/gtk/src/gtk_file.cpp
index 9c0e0009..b6607f75 100644
--- a/gtk/src/gtk_file.cpp
+++ b/gtk/src/gtk_file.cpp
@@ -422,7 +422,7 @@ S9xOpenROMDialog (void)
{
"*.smc", "*.SMC", "*.fig", "*.FIG", "*.sfc", "*.SFC",
"*.jma", "*.JMA", "*.zip", "*.ZIP", "*.gd3", "*.GD3",
- "*.swc", "*.SWC", "*.gz" , "*.GZ",
+ "*.swc", "*.SWC", "*.gz" , "*.GZ", "*.bs", "*.BS",
NULL
};
diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp
index 859d3f8b..38db20e4 100644
--- a/libretro/libretro.cpp
+++ b/libretro/libretro.cpp
@@ -178,7 +178,7 @@ void retro_get_system_info(struct retro_system_info *info)
info->library_name = "Snes9x";
info->library_version = VERSION;
- info->valid_extensions = "smc|sfc|swc|fig";
+ info->valid_extensions = "smc|sfc|swc|fig|bs";
info->need_fullpath = false;
info->block_extract = false;
}
diff --git a/memmap.cpp b/memmap.cpp
index c964c465..d55cfad4 100644
--- a/memmap.cpp
+++ b/memmap.cpp
@@ -957,9 +957,9 @@ static void S9xDeinterleaveGD24 (int, uint8 *);
static bool8 allASCII (uint8 *, int);
static bool8 is_SufamiTurbo_BIOS (const uint8 *, uint32);
static bool8 is_SufamiTurbo_Cart (const uint8 *, uint32);
-static bool8 is_SameGame_BIOS (const uint8 *, uint32);
+static bool8 is_BSCart_BIOS (const uint8 *, uint32);
static bool8 is_SameGame_Add_On (const uint8 *, uint32);
-static bool8 is_GNEXT_BIOS (const uint8 *, uint32);
+static bool8 is_BSCartSA1_BIOS(const uint8 *, uint32);
static bool8 is_GNEXT_Add_On (const uint8 *, uint32);
static uint32 caCRC32 (uint8 *, uint32, uint32 crc32 = 0xffffffff);
static uint32 ReadUPSPointer (const uint8 *, unsigned &, unsigned);
@@ -1243,10 +1243,22 @@ static bool8 is_SufamiTurbo_Cart (const uint8 *data, uint32 size)
return (FALSE);
}
-static bool8 is_SameGame_BIOS (const uint8 *data, uint32 size)
+static bool8 is_BSCart_BIOS(const uint8 *data, uint32 size)
{
- if (size == 0x100000 && strncmp((char *) (data + 0xffc0), "Same Game Tsume Game", 20) == 0)
+ if ((data[0x7FB2] == 0x5A) && (data[0x7FB5] != 0x20) && (data[0x7FDA] == 0x33))
+ {
+ Memory.LoROM = TRUE;
+ Memory.HiROM = FALSE;
+
return (TRUE);
+ }
+ else if ((data[0xFFB2] == 0x5A) && (data[0xFFB5] != 0x20) && (data[0xFFDA] == 0x33))
+ {
+ Memory.LoROM = FALSE;
+ Memory.HiROM = TRUE;
+
+ return (TRUE);
+ }
else
return (FALSE);
}
@@ -1259,9 +1271,14 @@ static bool8 is_SameGame_Add_On (const uint8 *data, uint32 size)
return (FALSE);
}
-static bool8 is_GNEXT_BIOS (const uint8 *data, uint32 size)
+static bool8 is_BSCartSA1_BIOS (const uint8 *data, uint32 size)
{
- if (size == 0x180000 && strncmp((char *) (data + 0x7fc0), "SFC SDGUNDAMGNEXT", 17) == 0)
+ //Same basic check as BSCart
+ if (!is_BSCart_BIOS(data, size))
+ return (FALSE);
+
+ //Checks if the game is Itoi's Bass Fishing No. 1 (ZBPJ) or SD Gundam G-NEXT (ZX3J)
+ if (strncmp((char *)(data + 0x7fb2), "ZBPJ", 4) == 0 || strncmp((char *)(data + 0x7fb2), "ZX3J", 4) == 0)
return (TRUE);
else
return (FALSE);
@@ -1866,11 +1883,11 @@ bool8 CMemory::LoadMultiCartInt ()
if (is_SufamiTurbo_Cart(ROM + Multi.cartOffsetA, Multi.cartSizeA))
Multi.cartType = 4;
else
- if (is_SameGame_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA))
- Multi.cartType = 3;
- else
- if (is_GNEXT_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA))
+ if (is_BSCartSA1_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA))
Multi.cartType = 5;
+ else
+ if (is_BSCart_BIOS(ROM + Multi.cartOffsetA, Multi.cartSizeA))
+ Multi.cartType = 3;
}
else
if (Multi.cartSizeB)
@@ -1918,11 +1935,8 @@ bool8 CMemory::LoadMultiCartInt ()
break;
case 3:
- r = LoadSameGame();
- break;
-
case 5:
- r = LoadGNEXT();
+ r = LoadBSCart();
break;
default:
@@ -1986,26 +2000,31 @@ bool8 CMemory::LoadSufamiTurbo ()
return (TRUE);
}
-bool8 CMemory::LoadSameGame ()
+bool8 CMemory::LoadBSCart ()
{
Multi.sramA = SRAM;
Multi.sramB = NULL;
- Multi.sramSizeA = ROM[0xffd8];
+ if (LoROM)
+ Multi.sramSizeA = ROM[0x7fd8];
+ else
+ Multi.sramSizeA = ROM[0xffd8];
+
Multi.sramMaskA = Multi.sramSizeA ? ((1 << (Multi.sramSizeA + 3)) * 128 - 1) : 0;
Multi.sramSizeB = 0;
Multi.sramMaskB = 0;
- if (Multi.cartSizeB)
- {
- if (!is_SameGame_Add_On(ROM + Multi.cartOffsetB, Multi.cartSizeB))
- Multi.cartSizeB = 0;
- }
-
- LoROM = FALSE;
- HiROM = TRUE;
CalculatedSize = Multi.cartSizeA;
+ if (Multi.cartSizeB == 0 && Multi.cartSizeA <= (MAX_ROM_SIZE - 0x100000 - Multi.cartOffsetA))
+ {
+ //Initialize 1MB Empty Memory Pack only if cart B is cleared
+ //It does not make a Memory Pack if game is loaded like a normal ROM
+ Multi.cartOffsetB = Multi.cartOffsetA + CalculatedSize;
+ Multi.cartSizeB = 0x100000;
+ memset(Memory.ROM + Multi.cartOffsetB, 0xFF, 0x100000);
+ }
+
return (TRUE);
}
@@ -2214,6 +2233,32 @@ bool8 CMemory::SaveSRAM (const char *filename)
return (FALSE);
}
+bool8 CMemory::SaveMPAK (const char *filename)
+{
+ if (Settings.BS || (Multi.cartSizeB && (Multi.cartType == 3)))
+ {
+ FILE *file;
+ int size;
+ char mempakName[PATH_MAX + 1];
+
+ strcpy(mempakName, filename);
+ size = 0x100000;
+ if (size)
+ {
+ file = fopen(mempakName, "wb");
+ if (file)
+ {
+ size_t ignore;
+ ignore = fwrite((char *)Memory.ROM + Multi.cartOffsetB, size, 1, file);
+ fclose(file);
+
+ return (TRUE);
+ }
+ }
+ }
+ return (FALSE);
+}
+
// initialization
static uint32 caCRC32 (uint8 *array, uint32 size, uint32 crc32)
@@ -2560,7 +2605,7 @@ void CMemory::InitROM (void)
Map_ExtendedHiROMMap();
else
if (Multi.cartType == 3)
- Map_SameGameHiROMMap();
+ Map_BSCartHiROMMap();
else
Map_HiROMMap();
}
@@ -2578,7 +2623,7 @@ void CMemory::InitROM (void)
if (Settings.SA1)
{
if (Multi.cartType == 5)
- Map_GNEXTSA1LoROMMap();
+ Map_BSSA1LoROMMap();
else
Map_SA1LoROMMap();
}
@@ -2592,6 +2637,13 @@ void CMemory::InitROM (void)
if (strncmp(ROMName, "WANDERERS FROM YS", 17) == 0)
Map_NoMAD1LoROMMap();
else
+ if (Multi.cartType == 3)
+ if (strncmp(ROMName, "SOUND NOVEL-TCOOL", 17) == 0 ||
+ strncmp(ROMName, "DERBY STALLION 96", 17) == 0)
+ Map_BSCartLoROMMap(1);
+ else
+ Map_BSCartLoROMMap(0);
+ else
if (strncmp(ROMName, "SOUND NOVEL-TCOOL", 17) == 0 ||
strncmp(ROMName, "DERBY STALLION 96", 17) == 0)
Map_ROM24MBSLoROMMap();
@@ -3263,9 +3315,9 @@ void CMemory::Map_SA1LoROMMap (void)
BWRAM = SRAM;
}
-void CMemory::Map_GNEXTSA1LoROMMap (void)
+void CMemory::Map_BSSA1LoROMMap(void)
{
- printf("Map_GNEXTSA1LoROMMap\n");
+ printf("Map_BSSA1LoROMMap\n");
map_System();
map_lorom_offset(0x00, 0x3f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
@@ -3281,9 +3333,6 @@ void CMemory::Map_GNEXTSA1LoROMMap (void)
for (int c = 0x40; c < 0x80; c++)
map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000);
- // FIXME: untested!
- map_hirom_offset(0x70, 0x7f, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
-
map_WRAM();
map_WriteProtectROM();
@@ -3343,26 +3392,6 @@ void CMemory::Map_ExtendedHiROMMap (void)
map_WriteProtectROM();
}
-void CMemory::Map_SameGameHiROMMap (void)
-{
- printf("Map_SameGameHiROMMap\n");
- map_System();
-
- map_hirom_offset(0x00, 0x1f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
- map_hirom_offset(0x20, 0x3f, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
- map_hirom_offset(0x40, 0x5f, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
- map_hirom_offset(0x60, 0x7f, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
- map_hirom_offset(0x80, 0x9f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
- map_hirom_offset(0xa0, 0xbf, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
- map_hirom_offset(0xc0, 0xdf, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
- map_hirom_offset(0xe0, 0xff, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
-
- map_HiROMSRAM();
- map_WRAM();
-
- map_WriteProtectROM();
-}
-
void CMemory::Map_SPC7110HiROMMap (void)
{
printf("Map_SPC7110HiROMMap\n");
@@ -3381,6 +3410,71 @@ void CMemory::Map_SPC7110HiROMMap (void)
map_WriteProtectROM();
}
+void CMemory::Map_BSCartLoROMMap(uint8 mapping)
+{
+ printf("Map_BSCartLoROMMap\n");
+
+ BSX.MMC[0x02] = 0x00;
+ BSX.MMC[0x0C] = 0x80;
+
+ map_System();
+
+ if (mapping)
+ {
+ map_lorom_offset(0x00, 0x1f, 0x8000, 0xffff, 0x100000, 0);
+ map_lorom_offset(0x20, 0x3f, 0x8000, 0xffff, 0x100000, 0x100000);
+ map_lorom_offset(0x80, 0x9f, 0x8000, 0xffff, 0x100000, 0x200000);
+ map_lorom_offset(0xa0, 0xbf, 0x8000, 0xffff, 0x100000, 0x100000);
+ }
+ else
+ {
+ map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
+ map_lorom(0x40, 0x7f, 0x0000, 0x7fff, CalculatedSize);
+ map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
+ map_lorom(0xc0, 0xff, 0x0000, 0x7fff, CalculatedSize);
+ }
+
+ map_LoROMSRAM();
+ map_index(0xc0, 0xef, 0x0000, 0xffff, MAP_BSX, MAP_TYPE_RAM);
+ map_WRAM();
+
+ map_WriteProtectROM();
+}
+
+void CMemory::Map_BSCartHiROMMap(void)
+{
+ printf("Map_BSCartHiROMMap\n");
+
+ BSX.MMC[0x02] = 0x80;
+ BSX.MMC[0x0C] = 0x80;
+
+ map_System();
+ map_hirom_offset(0x00, 0x1f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
+ map_hirom_offset(0x20, 0x3f, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
+ map_hirom_offset(0x40, 0x5f, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
+ map_hirom_offset(0x60, 0x7f, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
+ map_hirom_offset(0x80, 0x9f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
+ map_hirom_offset(0xa0, 0xbf, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
+ map_hirom_offset(0xc0, 0xdf, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
+
+ if ((ROM[Multi.cartOffsetB + 0xFF00] == 0x4D)
+ && (ROM[Multi.cartOffsetB + 0xFF02] == 0x50)
+ && ((ROM[Multi.cartOffsetB + 0xFF06] & 0xF0) == 0x70))
+ {
+ //Type 7 Memory Pack detection - if detected, emulate it as Mask ROM
+ map_hirom_offset(0xe0, 0xff, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
+ }
+ else
+ {
+ map_index(0xe0, 0xff, 0x0000, 0xffff, MAP_BSX, MAP_TYPE_RAM);
+ }
+
+ map_HiROMSRAM();
+ map_WRAM();
+
+ map_WriteProtectROM();
+}
+
// checksum
uint16 CMemory::checksum_calc_sum (uint8 *data, uint32 length)
@@ -4140,8 +4234,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{
printf("Using BPS patch %s", fname);
- ret = ReadBPSPatch(new fStream(patch_file), 0, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadBPSPatch(s, 0, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4163,8 +4258,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{
printf(" in %s", rom_filename);
- ret = ReadBPSPatch(new unzStream(file), offset, rom_size);
- unzCloseCurrentFile(file);
+ Stream *s = new unzStream(file);
+ ret = ReadBPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
printf("!\n");
@@ -4181,8 +4277,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{
printf("Using BPS patch %s", n);
- ret = ReadBPSPatch(new fStream(patch_file), 0, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadBPSPatch(s, 0, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4201,8 +4298,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{
printf("Using UPS patch %s", fname);
- ret = ReadUPSPatch(new fStream(patch_file), 0, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadUPSPatch(s, 0, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4224,8 +4322,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{
printf(" in %s", rom_filename);
- ret = ReadUPSPatch(new unzStream(file), offset, rom_size);
- unzCloseCurrentFile(file);
+ Stream *s = new unzStream(file);
+ ret = ReadUPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
printf("!\n");
@@ -4242,8 +4341,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{
printf("Using UPS patch %s", n);
- ret = ReadUPSPatch(new fStream(patch_file), 0, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadUPSPatch(s, 0, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4262,8 +4362,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{
printf("Using IPS patch %s", fname);
- ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4289,8 +4390,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf("Using IPS patch %s", fname);
- ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4325,8 +4427,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf("Using IPS patch %s", fname);
- ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4359,8 +4462,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf("Using IPS patch %s", fname);
- ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4389,8 +4493,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{
printf(" in %s", rom_filename);
- ret = ReadIPSPatch(new unzStream(file), offset, rom_size);
- unzCloseCurrentFile(file);
+ Stream *s = new unzStream(file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4416,8 +4521,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf(" in %s", rom_filename);
- ret = ReadIPSPatch(new unzStream(file), offset, rom_size);
- unzCloseCurrentFile(file);
+ Stream *s = new unzStream(file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4450,8 +4556,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf(" in %s", rom_filename);
- ret = ReadIPSPatch(new unzStream(file), offset, rom_size);
- unzCloseCurrentFile(file);
+ Stream *s = new unzStream(file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4482,8 +4589,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf(" in %s", rom_filename);
- ret = ReadIPSPatch(new unzStream(file), offset, rom_size);
- unzCloseCurrentFile(file);
+ Stream *s = new unzStream(file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4515,8 +4623,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
{
printf("Using IPS patch %s", n);
- ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4542,8 +4651,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf("Using IPS patch %s", n);
- ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4578,8 +4688,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf("Using IPS patch %s", n);
- ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
@@ -4612,8 +4723,9 @@ void CMemory::CheckForAnyPatch (const char *rom_filename, bool8 header, int32 &r
printf("Using IPS patch %s", n);
- ret = ReadIPSPatch(new fStream(patch_file), offset, rom_size);
- CLOSE_FSTREAM(patch_file);
+ Stream *s = new fStream(patch_file);
+ ret = ReadIPSPatch(s, offset, rom_size);
+ s->closeStream();
if (ret)
{
diff --git a/memmap.h b/memmap.h
index 6db01a7f..53826a98 100644
--- a/memmap.h
+++ b/memmap.h
@@ -293,13 +293,14 @@ struct CMemory
bool8 LoadMultiCart (const char *, const char *);
bool8 LoadMultiCartInt ();
bool8 LoadSufamiTurbo ();
- bool8 LoadSameGame ();
+ bool8 LoadBSCart ();
bool8 LoadGNEXT ();
bool8 LoadSRAM (const char *);
bool8 SaveSRAM (const char *);
void ClearSRAM (bool8 onlyNonSavedSRAM = 0);
bool8 LoadSRTC (void);
bool8 SaveSRTC (void);
+ bool8 SaveMPAK (const char *);
char * Safe (const char *);
char * SafeANK (const char *);
@@ -335,11 +336,12 @@ struct CMemory
void Map_SetaDSPLoROMMap (void);
void Map_SDD1LoROMMap (void);
void Map_SA1LoROMMap (void);
- void Map_GNEXTSA1LoROMMap (void);
+ void Map_BSSA1LoROMMap (void);
void Map_HiROMMap (void);
void Map_ExtendedHiROMMap (void);
- void Map_SameGameHiROMMap (void);
void Map_SPC7110HiROMMap (void);
+ void Map_BSCartLoROMMap(uint8);
+ void Map_BSCartHiROMMap(void);
uint16 checksum_calc_sum (uint8 *, uint32);
uint16 checksum_mirror_sum (uint8 *, uint32 &, uint32 mask = 0x800000);
diff --git a/movie.cpp b/movie.cpp
index af2d8b3f..87426b1f 100644
--- a/movie.cpp
+++ b/movie.cpp
@@ -807,7 +807,9 @@ int S9xMovieOpen (const char *filename, bool8 read_only)
restore_movie_settings();
lseek(fn, Movie.SaveStateOffset, SEEK_SET);
- stream = REOPEN_STREAM(fn, "rb");
+
+ // reopen stream to access as gzipped data
+ stream = REOPEN_STREAM(fn, "rb");
if (!stream)
return (FILE_NOT_FOUND);
@@ -820,7 +822,11 @@ int S9xMovieOpen (const char *filename, bool8 read_only)
else
result = S9xUnfreezeFromStream(stream);
- CLOSE_STREAM(stream);
+ // do not close stream but close FILE *
+ // (msvcrt will try to close all open FILE *handles on exit - if we do CLOSE_STREAM here
+ // the underlying file will be closed by zlib, causing problems when msvcrt tries to do it)
+ delete stream;
+ fclose(fd);
if (result != SUCCESS)
return (result);
diff --git a/sa1.cpp b/sa1.cpp
index 16f63490..20d45946 100644
--- a/sa1.cpp
+++ b/sa1.cpp
@@ -313,7 +313,16 @@ static void S9xSetSA1MemMap (uint32 which1, uint8 map)
for (int c = 0; c < 0x100; c += 16)
{
- uint8 *block = &Memory.ROM[(map & 7) * 0x100000 + (c << 12)];
+ uint8 *block;
+ if (Multi.cartType != 5)
+ block = &Memory.ROM[(map & 7) * 0x100000 + (c << 12)];
+ else
+ {
+ if ((map & 7) < 4)
+ block = Memory.ROM + Multi.cartOffsetA + ((map & 7) * 0x100000 + (c << 12));
+ else
+ block = Memory.ROM + Multi.cartOffsetB + (((map & 7) - 4) * 0x100000 + (c << 12));
+ }
for (int i = c; i < c + 16; i++)
Memory.Map[start + i] = SA1.Map[start + i] = block;
}
@@ -321,8 +330,26 @@ static void S9xSetSA1MemMap (uint32 which1, uint8 map)
for (int c = 0; c < 0x200; c += 16)
{
// conversion to int is needed here - map is promoted but which1 is not
- int32 offset = (((map & 0x80) ? map : which1) & 7) * 0x100000 + (c << 11) - 0x8000;
- uint8 *block = &Memory.ROM[offset];
+ int32 offset;
+ uint8 *block;
+ if (Multi.cartType != 5)
+ {
+ offset = (((map & 0x80) ? map : which1) & 7) * 0x100000 + (c << 11) - 0x8000;
+ block = &Memory.ROM[offset];
+ }
+ else
+ {
+ if ((map & 7) < 4)
+ {
+ offset = (((map & 0x80) ? map : which1) & 7) * 0x100000 + (c << 11) - 0x8000;
+ block = Memory.ROM + Multi.cartOffsetA + offset;
+ }
+ else
+ {
+ offset = (((map & 0x80) ? (map - 4) : which1) & 7) * 0x100000 + (c << 11) - 0x8000;
+ block = Memory.ROM + Multi.cartOffsetB + offset;
+ }
+ }
for (int i = c + 8; i < c + 16; i++)
Memory.Map[start2 + i] = SA1.Map[start2 + i] = block;
}
diff --git a/unix/configure b/unix/configure
index 699f40e6..14be08d5 100755
--- a/unix/configure
+++ b/unix/configure
@@ -5046,20 +5046,20 @@ fi
echo "$SYSTEM_ZIP_PKG_ERRORS" >&5
if test "x${with_system_zip}" != "xcheck"; then
- as_fn_error $? "--with-system-zip requested but no proper zlib found." "$LINENO" 5
+ as_fn_error $? "--with-system-zip requested but no proper minizip lib found." "$LINENO" 5
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: zlib not found. Build without SYSTEM_ZIP support." >&5
-$as_echo "$as_me: WARNING: zlib not found. Build without SYSTEM_ZIP support." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: minizip not found. Build without SYSTEM_ZIP support." >&5
+$as_echo "$as_me: WARNING: minizip not found. Build without SYSTEM_ZIP support." >&2;}
fi
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if test "x${with_system_zip}" != "xcheck"; then
- as_fn_error $? "--with-system-zip requested but no proper zlib found." "$LINENO" 5
+ as_fn_error $? "--with-system-zip requested but no proper minizip lib found." "$LINENO" 5
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: zlib not found. Build without SYSTEM_ZIP support." >&5
-$as_echo "$as_me: WARNING: zlib not found. Build without SYSTEM_ZIP support." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: minizip not found. Build without SYSTEM_ZIP support." >&5
+$as_echo "$as_me: WARNING: minizip not found. Build without SYSTEM_ZIP support." >&2;}
fi
else
diff --git a/unix/configure.ac b/unix/configure.ac
index 47f37808..28186c67 100644
--- a/unix/configure.ac
+++ b/unix/configure.ac
@@ -222,9 +222,9 @@ if test "x$enable_zip" = "xyes"; then
fi
S9XDEFS="$S9XDEFS -DSYSTEM_ZIP",
if test "x${with_system_zip}" != "xcheck"; then
- AC_MSG_ERROR([--with-system-zip requested but no proper zlib found.])
+ AC_MSG_ERROR([--with-system-zip requested but no proper minizip lib found.])
else
- AC_MSG_WARN([zlib not found. Build without SYSTEM_ZIP support.])
+ AC_MSG_WARN([minizip not found. Build without SYSTEM_ZIP support.])
fi
)
else
diff --git a/win32/CD3DCG.cpp b/win32/CD3DCG.cpp
index d5458cb6..95b61b5f 100644
--- a/win32/CD3DCG.cpp
+++ b/win32/CD3DCG.cpp
@@ -383,7 +383,7 @@ bool CD3DCG::LoadShader(const TCHAR *shaderFile)
hr = pDevice->CreateVertexBuffer(sizeof(VERTEX)*4,D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED,&pass.vertexBuffer,NULL);
if(FAILED(hr)) {
pass.vertexBuffer = NULL;
- DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex buffer"), hr);
+ DXTRACE_ERR_MSGBOX(L"Error creating vertex buffer", hr);
return false;
}
@@ -449,7 +449,7 @@ void CD3DCG::ensureTextureSize(LPDIRECT3DTEXTURE9 &tex, D3DXVECTOR2 &texSize,
texSize = wantedSize;
if(FAILED(hr)) {
- DXTRACE_ERR_MSGBOX(TEXT("Error while creating texture"), hr);
+ DXTRACE_ERR_MSGBOX(L"Error while creating texture", hr);
return;
}
}
@@ -860,7 +860,7 @@ void CD3DCG::setupVertexDeclaration(shaderPass &pass)
LPDIRECT3DVERTEXDECLARATION9 vertexDeclaration;
HRESULT hr = pDevice->CreateVertexDeclaration(vElems,&vertexDeclaration);
if(FAILED(hr)) {
- DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex declaration"), hr);
+ DXTRACE_ERR_MSGBOX(L"Error creating vertex declaration", hr);
}
if(pass.vertexDeclaration)
pass.vertexDeclaration->Release();
diff --git a/win32/CDirect3D.cpp b/win32/CDirect3D.cpp
index 1c69d49d..7fd8d6eb 100644
--- a/win32/CDirect3D.cpp
+++ b/win32/CDirect3D.cpp
@@ -272,7 +272,7 @@ bool CDirect3D::Initialize(HWND hWnd)
pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if(pD3D == NULL) {
- DXTRACE_ERR_MSGBOX(TEXT("Error creating initial D3D9 object"), 0);
+ DXTRACE_ERR_MSGBOX(L"Error creating initial D3D9 object", 0);
return false;
}
@@ -290,19 +290,19 @@ bool CDirect3D::Initialize(HWND hWnd)
&dPresentParams,
&pDevice);
if(FAILED(hr)) {
- DXTRACE_ERR_MSGBOX(TEXT("Error creating D3D9 device"), hr);
+ DXTRACE_ERR_MSGBOX(L"Error creating D3D9 device", hr);
return false;
}
hr = pDevice->CreateVertexBuffer(sizeof(vertexStream),D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED,&vertexBuffer,NULL);
if(FAILED(hr)) {
- DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex buffer"), hr);
+ DXTRACE_ERR_MSGBOX(L"Error creating vertex buffer", hr);
return false;
}
hr = pDevice->CreateVertexDeclaration(vertexElems,&vertexDeclaration);
if(FAILED(hr)) {
- DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex declaration"), hr);
+ DXTRACE_ERR_MSGBOX(L"Error creating vertex declaration", hr);
return false;
}
@@ -312,7 +312,7 @@ bool CDirect3D::Initialize(HWND hWnd)
cgContext = cgCreateContext();
hr = cgD3D9SetDevice(pDevice);
if(FAILED(hr)) {
- DXTRACE_ERR_MSGBOX(TEXT("Error setting cg device"), hr);
+ DXTRACE_ERR_MSGBOX(L"Error setting cg device", hr);
}
cgShader = new CD3DCG(cgContext,pDevice);
}
@@ -650,14 +650,14 @@ void CDirect3D::Render(SSurface Src)
ResetDevice();
return;
default:
- DXTRACE_ERR_MSGBOX( TEXT("Internal driver error"), hr);
+ DXTRACE_ERR_MSGBOX( L"Internal driver error", hr);
return;
}
}
//BlankTexture(drawSurface);
if(FAILED(hr = drawSurface->LockRect(0, &lr, NULL, 0))) {
- DXTRACE_ERR_MSGBOX( TEXT("Unable to lock texture"), hr);
+ DXTRACE_ERR_MSGBOX( L"Unable to lock texture", hr);
return;
} else {
Dst.Surface = (unsigned char *)lr.pBits;
@@ -757,7 +757,7 @@ void CDirect3D::CreateDrawSurface()
NULL );
if(FAILED(hr)) {
- DXTRACE_ERR_MSGBOX(TEXT("Error while creating texture"), hr);
+ DXTRACE_ERR_MSGBOX(L"Error while creating texture", hr);
return;
}
}
@@ -787,7 +787,7 @@ bool CDirect3D::BlankTexture(LPDIRECT3DTEXTURE9 texture)
HRESULT hr;
if(FAILED(hr = texture->LockRect(0, &lr, NULL, 0))) {
- DXTRACE_ERR_MSGBOX( TEXT("Unable to lock texture"), hr);
+ DXTRACE_ERR_MSGBOX( L"Unable to lock texture", hr);
return false;
} else {
memset(lr.pBits, 0, lr.Pitch * quadTextureSize);
@@ -938,7 +938,7 @@ bool CDirect3D::ResetDevice()
}
if(FAILED(hr = pDevice->Reset(&dPresentParams))) {
- DXTRACE_ERR(TEXT("Unable to reset device"), hr);
+ DXTRACE_ERR(L"Unable to reset device", hr);
return false;
}
diff --git a/win32/CXAudio2.cpp b/win32/CXAudio2.cpp
index 84fa533f..7bfdb6ef 100644
--- a/win32/CXAudio2.cpp
+++ b/win32/CXAudio2.cpp
@@ -234,7 +234,7 @@ bool CXAudio2::InitXAudio2(void)
HRESULT hr;
if ( FAILED(hr = XAudio2Create( &pXAudio2, 0 , XAUDIO2_DEFAULT_PROCESSOR ) ) ) {
- DXTRACE_ERR_MSGBOX(TEXT("Unable to create XAudio2 object."),hr);
+ DXTRACE_ERR_MSGBOX(L"Unable to create XAudio2 object.",hr);
MessageBox (GUI.hWnd, TEXT("\
Unable to initialize XAudio2. You will not be able to hear any\n\
sound effects or music while playing.\n\n\
@@ -257,7 +257,7 @@ bool CXAudio2::InitVoices(void)
HRESULT hr;
if ( FAILED(hr = pXAudio2->CreateMasteringVoice( &pMasterVoice, (Settings.Stereo?2:1),
Settings.SoundPlaybackRate, 0, 0 , NULL ) ) ) {
- DXTRACE_ERR_MSGBOX(TEXT("Unable to create mastering voice."),hr);
+ DXTRACE_ERR_MSGBOX(L"Unable to create mastering voice.",hr);
return false;
}
@@ -272,7 +272,7 @@ bool CXAudio2::InitVoices(void)
if( FAILED(hr = pXAudio2->CreateSourceVoice(&pSourceVoice, (WAVEFORMATEX*)&wfx,
XAUDIO2_VOICE_NOSRC , XAUDIO2_DEFAULT_FREQ_RATIO, this, NULL, NULL ) ) ) {
- DXTRACE_ERR_MSGBOX(TEXT("Unable to create source voice."),hr);
+ DXTRACE_ERR_MSGBOX(L"Unable to create source voice.",hr);
return false;
}
diff --git a/win32/rsrc/resource.h b/win32/rsrc/resource.h
index 0f6bf528..07ec2620 100644
--- a/win32/rsrc/resource.h
+++ b/win32/rsrc/resource.h
@@ -496,13 +496,14 @@
#define ID_WINDOW_SIZE_4X 40172
#define ID_DEBUG_APU_TRACE 40173
#define ID_EMULATION_BACKGROUNDINPUT 40174
+#define ID_SAVEMEMPACK 40175
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 151
-#define _APS_NEXT_COMMAND_VALUE 40175
+#define _APS_NEXT_COMMAND_VALUE 40176
#define _APS_NEXT_CONTROL_VALUE 3018
#define _APS_NEXT_SYMED_VALUE 101
#endif
diff --git a/win32/rsrc/snes9x.rc b/win32/rsrc/snes9x.rc
index 5c11c0a3..0629f188 100644
--- a/win32/rsrc/snes9x.rc
+++ b/win32/rsrc/snes9x.rc
@@ -716,14 +716,15 @@ IDB_HIDDENFOLDER BITMAP "hiddir.bmp"
// remains consistent on all systems.
IDI_ICON1 ICON "icon1.ico"
+
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,5,3,0
- PRODUCTVERSION 1,5,3,0
+ FILEVERSION 1,5,4,1
+ PRODUCTVERSION 1,5,4,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -822,6 +823,7 @@ BEGIN
MENUITEM "S&ave SPC Data", ID_FILE_SAVE_SPC_DATA
MENUITEM "Save Screenshot", ID_SAVESCREENSHOT
MENUITEM "Sa&ve S-RAM Data", ID_FILE_SAVE_SRAM_DATA
+ MENUITEM "Save Memory Pack", ID_SAVEMEMPACK
END
MENUITEM "ROM Information...", IDM_ROM_INFO
MENUITEM SEPARATOR
diff --git a/win32/snes9xw.vcxproj.filters b/win32/snes9xw.vcxproj.filters
index eb02b1ac..8020f00f 100644
--- a/win32/snes9xw.vcxproj.filters
+++ b/win32/snes9xw.vcxproj.filters
@@ -244,7 +244,7 @@
GUI
- Emu
+ APU
@@ -543,7 +543,7 @@
GUI
- Emu
+ APU
diff --git a/win32/wlanguage.h b/win32/wlanguage.h
index 2c68bede..50735f57 100644
--- a/win32/wlanguage.h
+++ b/win32/wlanguage.h
@@ -597,6 +597,8 @@ Nintendo is a trade mark.")
#define INFO_SAVE_SPC "Saving SPC Data."
+#define MPAK_SAVE_FAILED "Failed to save Memory Pack."
+
#define CHEATS_INFO_ENABLED "Cheats enabled."
#define CHEATS_INFO_DISABLED "Cheats disabled."
#define CHEATS_INFO_ENABLED_NONE "Cheats enabled. (None are active.)"
diff --git a/win32/wsnes9x.cpp b/win32/wsnes9x.cpp
index 8a303486..b4de0412 100644
--- a/win32/wsnes9x.cpp
+++ b/win32/wsnes9x.cpp
@@ -2016,7 +2016,7 @@ LRESULT CALLBACK WinProc(
{
char localhostname [256];
gethostname(localhostname,256);
- _stprintf(localhostmsg, TEXT("Your host name is: %s\nYour port number is: %d"), _tFromChar(localhostname), Settings.Port);
+ _stprintf(localhostmsg, TEXT("Your host name is: %s\nYour port number is: %d"), (TCHAR *)_tFromChar(localhostname), Settings.Port);
MessageBox(GUI.hWnd,localhostmsg,TEXT("Note"),MB_OK);
}
}
@@ -2248,6 +2248,17 @@ LRESULT CALLBACK WinProc(
if(!success)
S9xMessage(S9X_ERROR, S9X_FREEZE_FILE_INFO, SRM_SAVE_FAILED);
} break;
+ case ID_SAVEMEMPACK: {
+ const char *filename = S9xGetFilenameInc(".bs", SRAM_DIR);
+ bool8 success = Memory.SaveMPAK(filename);
+ if (!success)
+ S9xMessage(S9X_ERROR, 0, MPAK_SAVE_FAILED);
+ else
+ {
+ sprintf(String, "Saved Memory Pack %s", filename);
+ S9xMessage(S9X_INFO, 0, String);
+ }
+ } break;
case ID_FILE_RESET:
#ifdef NETPLAY_SUPPORT
if (Settings.NetPlayServer)
@@ -2423,7 +2434,7 @@ LRESULT CALLBACK WinProc(
{
if (!LoadROM(GUI.RecentGames [i])) {
- sprintf (String, ERR_ROM_NOT_FOUND, _tToChar(GUI.RecentGames [i]));
+ sprintf (String, ERR_ROM_NOT_FOUND, (char *)_tToChar(GUI.RecentGames [i]));
S9xMessage (S9X_ERROR, S9X_ROM_NOT_FOUND, String);
S9xRemoveFromRecentGames(i);
}
@@ -2694,7 +2705,7 @@ LRESULT CALLBACK WinProc(
{
TCHAR buf [NP_MAX_ACTION_LEN + 10];
- _stprintf (buf, TEXT("%s %3d%%"), _tFromChar(NetPlay.ActionMsg), (int) lParam);
+ _stprintf (buf, TEXT("%s %3d%%"), (TCHAR *)_tFromChar(NetPlay.ActionMsg), (int) lParam);
SetWindowText (GUI.hWnd, buf);
}
#if 0
@@ -3693,7 +3704,7 @@ loop_exit:
void FreezeUnfreeze (int slot, bool8 freeze)
{
- const char *filename;
+ char filename[_MAX_PATH +1];
char ext [_MAX_EXT + 1];
#ifdef NETPLAY_SUPPORT
@@ -3706,7 +3717,7 @@ void FreezeUnfreeze (int slot, bool8 freeze)
#endif
snprintf(ext, _MAX_EXT, ".%03d", slot);
- filename = S9xGetFilename(ext,SNAPSHOT_DIR);
+ strcpy(filename, S9xGetFilename(ext, SNAPSHOT_DIR));
S9xSetPause (PAUSE_FREEZE_FILE);
@@ -5015,7 +5026,7 @@ INT_PTR CALLBACK DlgInfoProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
SetTextColor((HDC)wParam, GUI.InfoColor);
SetBkColor((HDC)wParam, RGB(0,0,0));
- return (BOOL)GetStockObject( BLACK_BRUSH );
+ return (INT_PTR)GetStockObject( BLACK_BRUSH );
}
break;
case WM_PAINT:
@@ -5309,7 +5320,7 @@ void rominfo(const TCHAR *filename, TCHAR *namebuffer, TCHAR *sizebuffer)
lstrcpy(namebuffer, ROM_ITEM_DESCNOTAVAILABLE);
lstrcpy(sizebuffer, TEXT("? Mbits"));
-#ifdef ZLIB
+#ifdef UNZIP_SUPPORT
if(IsCompressed(filename))
{
unzFile uf = unzOpen(_tToChar(filename));
@@ -7006,6 +7017,7 @@ void MakeExtFile(void)
out<<"smcN"<