[BS-X] BS-X Memory Mapping fixes

- Cleanups
- Proper PSRAM mapping (forgotten mapping and "over"mapping fix)
- Flash Interface not limited to bank 0xC0
(MMC would not interfere because of its particular addressing)
This commit is contained in:
LuigiBlood 2017-12-17 00:13:47 +01:00
parent 99e678f049
commit d89d7681ad
1 changed files with 233 additions and 188 deletions

421
bsx.cpp
View File

@ -374,16 +374,32 @@ static void BSX_Map_MMC (void)
static void BSX_Map_FlashIO (void)
{
if (BSX.MMC[0x0C] || BSX.MMC[0x0D])
int i, c;
if (BSX.prevMMC[0x0C])
{
// Bank C0:0000, 2AAA, 5555, FF00-FF1F
for (int c = 0; c < 16; c++)
// Banks 00->3F and 80->BF
for (c = 0; c < 0x400; c += 16)
{
Map[c + 0xC00] = (uint8 *) MAP_BSX;
BlockIsRAM[c + 0xC00] = TRUE;
BlockIsROM[c + 0xC00] = FALSE;
for (i = c + 8; i < c + 16; i++)
{
Map[i] = Map[i + 0x800] = (uint8 *)MAP_BSX;
BlockIsRAM[i] = BlockIsRAM[i + 0x800] = TRUE;
BlockIsROM[i] = BlockIsROM[i + 0x800] = FALSE;
}
}
}
// 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] = (uint8 *)MAP_BSX;
BlockIsRAM[i + 0x400] = BlockIsRAM[i + 0xC00] = TRUE;
BlockIsROM[i + 0x400] = BlockIsROM[i + 0xC00] = FALSE;
}
}
}
}
static void BSX_Map_SRAM (void)
@ -405,39 +421,49 @@ static void map_psram_mirror_sub (uint32 bank)
bank <<= 4;
if (BSX.MMC[0x02])
if (BSX.prevMMC[0x02])
{
for (c = 0; c < 0x100; c += 16)
//HiROM
for (c = 0; c < 0x80; c += 16)
{
for (i = c; i < c + 16; i++)
if ((bank & 0x7F0) >= 0x400)
{
Map[i + bank] = &PSRAM[(c << 12) % PSRAM_SIZE];
BlockIsRAM[i + bank] = TRUE;
BlockIsROM[i + bank] = FALSE;
for (i = c; i < c + 16; i++)
{
Map[i + bank] = &PSRAM[(c << 12) % PSRAM_SIZE];
BlockIsRAM[i + bank] = TRUE;
BlockIsROM[i + bank] = FALSE;
}
}
else
{
for (i = c + 8; i < c + 16; i++)
{
Map[i + bank] = &PSRAM[(c << 12) % PSRAM_SIZE];
BlockIsRAM[i + bank] = TRUE;
BlockIsROM[i + bank] = FALSE;
}
}
}
}
else
{
//LoROM
for (c = 0; c < 0x100; c += 16)
{
if ((bank & 0x7F) >= 0x40)
if ((bank & 0x7F0) >= 0x400)
{
for (i = c; i < c + 8; i++)
Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE];
for (i = c; i < c + 8; i++)
{
Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE];
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 + 8; i < c + 16; i++)
{
Map[i + bank] = &PSRAM[(c << 11) % PSRAM_SIZE] - 0x8000;
BlockIsRAM[i + bank] = TRUE;
BlockIsROM[i + bank] = FALSE;
}
@ -449,95 +475,118 @@ static void BSX_Map_PSRAM(void)
{
int c;
if (!BSX.MMC[0x02])
if (!BSX.prevMMC[0x02])
{
//LoROM Mode
if (!BSX.MMC[0x05] && !BSX.MMC[0x06])
if (!BSX.prevMMC[0x05] && !BSX.prevMMC[0x06])
{
//Map PSRAM to 00-0F/80-8F
if (BSX.MMC[0x03])
if (BSX.prevMMC[0x03])
map_psram_mirror_sub(0x00);
if (BSX.MMC[0x04])
if (BSX.prevMMC[0x04])
map_psram_mirror_sub(0x80);
}
else if (BSX.MMC[0x05] && !BSX.MMC[0x06])
else if (BSX.prevMMC[0x05] && !BSX.prevMMC[0x06])
{
//Map PSRAM to 20-2F/A0-AF
if (BSX.MMC[0x03])
if (BSX.prevMMC[0x03])
map_psram_mirror_sub(0x20);
if (BSX.MMC[0x04])
if (BSX.prevMMC[0x04])
map_psram_mirror_sub(0xA0);
}
else if (!BSX.MMC[0x05] && BSX.MMC[0x06])
else if (!BSX.prevMMC[0x05] && BSX.prevMMC[0x06])
{
//Map PSRAM to 40-4F/C0-CF
if (BSX.MMC[0x03])
if (BSX.prevMMC[0x03])
map_psram_mirror_sub(0x40);
if (BSX.MMC[0x04])
if (BSX.prevMMC[0x04])
map_psram_mirror_sub(0xC0);
}
else
{
//Map PSRAM to 60-6F/E0-EF
if (BSX.MMC[0x03])
if (BSX.prevMMC[0x03])
map_psram_mirror_sub(0x60);
if (BSX.MMC[0x04])
if (BSX.prevMMC[0x04])
map_psram_mirror_sub(0xE0);
}
//Map PSRAM to 70-7D/F0-FF
if (BSX.MMC[0x03])
if (BSX.prevMMC[0x03])
map_psram_mirror_sub(0x70);
if (BSX.MMC[0x04])
if (BSX.prevMMC[0x04])
map_psram_mirror_sub(0xF0);
}
else
{
//HiROM Mode
if (!BSX.MMC[0x05] && !BSX.MMC[0x06])
if (!BSX.prevMMC[0x05] && !BSX.prevMMC[0x06])
{
//Map PSRAM to 40-47/C0-C7
if (BSX.MMC[0x03])
//Map PSRAM to 00-07/40-47 / 80-87/C0-C7
if (BSX.prevMMC[0x03])
{
map_psram_mirror_sub(0x00);
map_psram_mirror_sub(0x40);
}
if (BSX.MMC[0x04])
if (BSX.prevMMC[0x04])
{
map_psram_mirror_sub(0x80);
map_psram_mirror_sub(0xC0);
}
}
else if (BSX.MMC[0x05] && !BSX.MMC[0x06])
else if (BSX.prevMMC[0x05] && !BSX.prevMMC[0x06])
{
//Map PSRAM to 50-57/D0-D7
if (BSX.MMC[0x03])
//Map PSRAM to 10-17/50-57 / 90-97-D0-D7
if (BSX.prevMMC[0x03])
{
map_psram_mirror_sub(0x10);
map_psram_mirror_sub(0x50);
}
if (BSX.MMC[0x04])
if (BSX.prevMMC[0x04])
{
map_psram_mirror_sub(0x90);
map_psram_mirror_sub(0xD0);
}
}
else if (!BSX.MMC[0x05] && BSX.MMC[0x06])
else if (!BSX.prevMMC[0x05] && BSX.prevMMC[0x06])
{
//Map PSRAM to 60-67/E0-E7
if (BSX.MMC[0x03])
//Map PSRAM to 20-27/60-67 / A0-A7/E0-E7
if (BSX.prevMMC[0x03])
{
map_psram_mirror_sub(0x20);
map_psram_mirror_sub(0x60);
}
if (BSX.MMC[0x04])
if (BSX.prevMMC[0x04])
{
map_psram_mirror_sub(0xA0);
map_psram_mirror_sub(0xE0);
}
}
else
{
//Map PSRAM to 70-77/F0-F7
if (BSX.MMC[0x03])
//Map PSRAM to 30-37/70-77 / B0-B7/F0-F7
if (BSX.prevMMC[0x03])
{
map_psram_mirror_sub(0x30);
map_psram_mirror_sub(0x70);
}
if (BSX.MMC[0x04])
if (BSX.prevMMC[0x04])
{
map_psram_mirror_sub(0xB0);
map_psram_mirror_sub(0xF0);
}
}
if (BSX.MMC[0x03])
if (BSX.prevMMC[0x03])
{
//Map PSRAM to 20->3F:6000-7FFF
for (c = 0x200; c < 0x400; c += 16)
@ -551,7 +600,7 @@ static void BSX_Map_PSRAM(void)
}
}
if (BSX.MMC[0x04])
if (BSX.prevMMC[0x04])
{
//Map PSRAM to A0->BF:6000-7FFF
for (c = 0xA00; c < 0xC00; c += 16)
@ -572,7 +621,7 @@ static void BSX_Map_BIOS (void)
int i,c;
// Banks 00->1F:8000-FFFF
if (BSX.MMC[0x07])
if (BSX.prevMMC[0x07])
{
for (c = 0; c < 0x200; c += 16)
{
@ -586,7 +635,7 @@ static void BSX_Map_BIOS (void)
}
// Banks 80->9F:8000-FFFF
if (BSX.MMC[0x08])
if (BSX.prevMMC[0x08])
{
for (c = 0; c < 0x200; c += 16)
{
@ -626,18 +675,20 @@ static void BSX_Map (void)
memcpy(BSX.prevMMC, BSX.MMC, sizeof(BSX.MMC));
printf("BSX MAP\n");
MapROM = FlashROM;
FlashSize = FLASH_SIZE;
BSX_Map_SNES();
if (BSX.MMC[0x02])
if (BSX.prevMMC[0x02])
BSX_Map_HiROM();
else
BSX_Map_LoROM();
BSX_Map_FlashIO();
BSX_Map_PSRAM();
BSX_Map_SNES();
BSX_Map_SRAM();
BSX_Map_RAM();
@ -653,22 +704,22 @@ static void BSX_Map (void)
static uint8 BSX_Get_Bypass_FlashIO (uint32 offset)
{
MapROM = FlashROM = Memory.ROM + Multi.cartOffsetB;
if (BSX.MMC[0x02])
return (MapROM[offset & 0x0FFFFF]);
if (BSX.prevMMC[0x02])
{
return (FlashROM[offset & 0x0FFFFF]);
}
else
return (MapROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)]);
{
return (FlashROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)]);
}
}
static void BSX_Set_Bypass_FlashIO (uint32 offset, uint8 byte)
{
MapROM = FlashROM = Memory.ROM + Multi.cartOffsetB;
if (BSX.MMC[0x02])
MapROM[offset & 0x0FFFFF] = MapROM[offset & 0x0FFFFF] & byte;
if (BSX.prevMMC[0x02])
FlashROM[offset & 0x0FFFFF] = FlashROM[offset & 0x0FFFFF] & byte;
else
MapROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)] = MapROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)] & byte;
FlashROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)] = FlashROM[(offset & 0x1F0000) >> 1 | (offset & 0x7FFF)] & byte;
}
uint8 S9xGetBSX (uint32 address)
@ -678,18 +729,17 @@ uint8 S9xGetBSX (uint32 address)
uint8 t = 0;
// MMC
if ((bank >= 0x01 && bank <= 0x0E))
if ((bank >= 0x01 && bank <= 0x0E) && ((address & 0xF000) == 0x5000))
return (BSX.MMC[bank]);
// Flash IO
if (bank >= 0xC0)
{
// default: read-through mode
t = BSX_Get_Bypass_FlashIO(address);
// Flash Mapping
// note: may be more registers, purposes unknown
switch (offset)
{
// default: read-through mode
t = BSX_Get_Bypass_FlashIO(address);
// note: may be more registers, purposes unknown
switch (offset)
{
case 0x0002:
case 0x8002:
if (BSX.flash_bsr)
@ -721,14 +771,12 @@ uint8 S9xGetBSX (uint32 address)
if (BSX.read_enable)
t = flashcard[offset - 0xFF00];
break;
}
if (BSX.flash_csr)
{
t = 0x80; // Compatible Status Register
BSX.flash_csr = false;
}
}
if (BSX.flash_csr)
{
t = 0x80; // Compatible Status Register
BSX.flash_csr = false;
}
return (t);
@ -739,7 +787,7 @@ void S9xSetBSX (uint8 byte, uint32 address)
uint8 bank = (address >> 16) & 0xFF;
// MMC
if ((bank >= 0x01 && bank <= 0x0E))
if ((bank >= 0x01 && bank <= 0x0E) && ((address & 0xF000) == 0x5000))
{
//Avoid updating the memory map when it is not needed
if (bank == 0x0E && BSX.dirty)
@ -756,118 +804,115 @@ void S9xSetBSX (uint8 byte, uint32 address)
}
// Flash IO
if (bank >= 0xC0)
// Write to Flash
if (BSX.write_enable)
{
// Write to Flash
if (BSX.write_enable)
BSX_Set_Bypass_FlashIO(address, byte);
BSX.write_enable = false;
return;
}
// Flash Command Handling
if (BSX.MMC[0xC]) {
//Memory Pack Type 1 & 3 & 4
BSX.flash_command <<= 8;
BSX.flash_command |= byte;
switch (BSX.flash_command & 0xFF)
{
BSX_Set_Bypass_FlashIO(address, byte);
//MapROM[address & 0x3FFFFF] = byte;
BSX.write_enable = false;
return;
}
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;
// Flash Command Handling
if (BSX.MMC[0xC]) {
//Memory Pack Type 1 & 3 & 4
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 & 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 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 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;
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 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 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 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 0x75:
//Show Page Buffer / Vendor Info
BSX.flash_csr = false;
BSX.read_enable = true;
BSX.flash_cmd_done = true;
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 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])
FlashROM[(address & 0x0F0000) + x] = 0xFF;
else
FlashROM[((address & 0x1E0000) >> 1) + x] = 0xFF;
}
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
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 < 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;
for (x = 0; x < FLASH_SIZE; x++) {
//BSX_Set_Bypass_FlashIO(x, 0xFF);
FlashROM[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;
}
case 0x38D0: //Flashcart Reset
break;
}
break;
}
}
}
@ -875,7 +920,7 @@ void S9xSetBSX (uint8 byte, uint32 address)
void S9xBSXSetStream1 (uint8 count)
{
if (BSX.sat_stream1.is_open())
BSX.sat_stream1.close(); //If Stream1 already opened for one file: Close it.
BSX.sat_stream1.close(); //If Stream already opened for one file: Close it.
char path[PATH_MAX + 1], name[PATH_MAX + 1];
@ -907,7 +952,7 @@ void S9xBSXSetStream1 (uint8 count)
void S9xBSXSetStream2 (uint8 count)
{
if (BSX.sat_stream2.is_open())
BSX.sat_stream2.close(); //If Stream1 already opened for one file: Close it.
BSX.sat_stream2.close(); //If Stream already opened for one file: Close it.
char path[PATH_MAX + 1], name[PATH_MAX + 1];