diff --git a/bsx.cpp b/bsx.cpp index a0d27914..339adf24 100644 --- a/bsx.cpp +++ b/bsx.cpp @@ -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) { @@ -628,16 +677,16 @@ static void BSX_Map (void) 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 +702,24 @@ static void BSX_Map (void) static uint8 BSX_Get_Bypass_FlashIO (uint32 offset) { - MapROM = FlashROM = Memory.ROM + Multi.cartOffsetB; + //For games other than BS-X + 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; + //For games other than BS-X + 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,134 +787,139 @@ 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)) { - BSX.MMC[bank] = byte; - if (bank == 0x0E) + //Avoid updating the memory map when it is not needed + if (bank == 0x0E && BSX.dirty) + { BSX_Map(); + BSX.dirty = FALSE; + } + else if (bank != 0x0E && BSX.MMC[bank] != byte) + { + BSX.dirty = TRUE; + } + + BSX.MMC[bank] = byte; } // 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); - //MapROM[address & 0x3FFFFF] = byte; + BSX_Set_Bypass_FlashIO(address, byte); + BSX.write_enable = false; + return; + } + + // Flash Command Handling + + //Memory Pack Type 1 & 3 & 4 + BSX.flash_command <<= 8; + BSX.flash_command |= byte; + + 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; - return; - } + 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 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 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 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 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 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 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 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 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 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 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; - - 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; + 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 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); + FlashROM[x] = 0xFF; + } + } + break; + + case 0x38D0: //Flashcart Reset + break; } - } + break; } } 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]; @@ -884,7 +937,7 @@ void S9xBSXSetStream1 (uint8 count) long str1size = BSX.sat_stream1.tellg(); BSX.sat_stream1.seekg(0, BSX.sat_stream1.beg); float QueueSize = str1size / 22.; - BSX.PPU[0x218A - BSXPPUBASE] = (uint8)(ceil(QueueSize)); + BSX.sat_stream1_queue = (uint16)(ceil(QueueSize)); BSX.PPU[0x218D - BSXPPUBASE] = 0; BSX.sat_stream1_first = TRUE; BSX.sat_stream1_loaded = TRUE; @@ -898,7 +951,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]; @@ -916,7 +969,7 @@ void S9xBSXSetStream2 (uint8 count) long str2size = BSX.sat_stream2.tellg(); BSX.sat_stream2.seekg(0, BSX.sat_stream2.beg); float QueueSize = str2size / 22.; - BSX.PPU[0x2190 - BSXPPUBASE] = (uint8)(ceil(QueueSize)); + BSX.sat_stream2_queue = (uint16)(ceil(QueueSize)); BSX.PPU[0x2193 - BSXPPUBASE] = 0; BSX.sat_stream2_first = TRUE; BSX.sat_stream2_loaded = TRUE; @@ -996,7 +1049,7 @@ uint8 S9xGetBSXPPU (uint16 address) break; } - if (BSX.PPU[0x218A - BSXPPUBASE] <= 0) + if (BSX.sat_stream1_queue <= 0) { BSX.sat_stream1_count++; S9xBSXSetStream1(BSX.sat_stream1_count - 1); @@ -1009,7 +1062,14 @@ uint8 S9xGetBSXPPU (uint16 address) } if (BSX.sat_stream1_loaded) + { + //Lock at 0x7F for bigger packets + if (BSX.sat_stream1_queue >= 128) + BSX.PPU[0x218A - BSXPPUBASE] = 0x7F; + else + BSX.PPU[0x218A - BSXPPUBASE] = BSX.sat_stream1_queue; t = BSX.PPU[0x218A - BSXPPUBASE]; + } else t = 0; break; @@ -1033,9 +1093,9 @@ uint8 S9xGetBSXPPU (uint16 address) BSX.sat_stream1_first = FALSE; } - BSX.PPU[0x218A - BSXPPUBASE]--; + BSX.sat_stream1_queue--; - if (BSX.PPU[0x218A - BSXPPUBASE] == 0) + if (BSX.sat_stream1_queue == 0) { //Last packet temp |= 0x80; @@ -1107,7 +1167,7 @@ uint8 S9xGetBSXPPU (uint16 address) break; } - if (BSX.PPU[0x2190 - BSXPPUBASE] <= 0) + if (BSX.sat_stream2_queue <= 0) { BSX.sat_stream2_count++; S9xBSXSetStream2(BSX.sat_stream2_count - 1); @@ -1120,7 +1180,13 @@ uint8 S9xGetBSXPPU (uint16 address) } if (BSX.sat_stream2_loaded) + { + if (BSX.sat_stream2_queue >= 128) + BSX.PPU[0x2190 - BSXPPUBASE] = 0x7F; + else + BSX.PPU[0x2190 - BSXPPUBASE] = BSX.sat_stream2_queue; t = BSX.PPU[0x2190 - BSXPPUBASE]; + } else t = 0; break; @@ -1144,9 +1210,9 @@ uint8 S9xGetBSXPPU (uint16 address) BSX.sat_stream2_first = FALSE; } - BSX.PPU[0x2190 - BSXPPUBASE]--; + BSX.sat_stream2_queue--; - if (BSX.PPU[0x2190 - BSXPPUBASE] == 0) + if (BSX.sat_stream2_queue == 0) { //Last packet temp |= 0x80; @@ -1479,6 +1545,10 @@ void S9xResetBSX (void) BSX.MMC[0x07] = BSX.MMC[0x08] = 0x80; BSX.MMC[0x0E] = 0x80; + // default register values + BSX.PPU[0x2196 - BSXPPUBASE] = 0x10; + BSX.PPU[0x2197 - BSXPPUBASE] = 0x80; + // stream reset BSX.sat_pf_latch1_enable = BSX.sat_dt_latch1_enable = FALSE; BSX.sat_pf_latch2_enable = BSX.sat_dt_latch2_enable = FALSE; diff --git a/bsx.h b/bsx.h index 235e5beb..0bbf28c1 100644 --- a/bsx.h +++ b/bsx.h @@ -227,6 +227,7 @@ struct SBSX bool sat_stream1_loaded, sat_stream2_loaded; bool sat_stream1_first, sat_stream2_first; uint8 sat_stream1_count, sat_stream2_count; + uint16 sat_stream1_queue, sat_stream2_queue; }; extern struct SBSX BSX;