📄 memmap.cpp
字号:
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 : 8; } } // 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] = 8; BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = 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) return ("Corrupt"); sprintf (tmp, "%dKb", (SRAMMask + 1) / 1024); return (tmp);}const char *CMemory::Size (){ static char tmp [20]; if (ROMSize < 7 || ROMSize - 7 > 23) return ("Corrupt"); 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) return ("ROM only"); sprintf (tmp, "%s", Contents [(ROMType & 0xf) % 3]); 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.Mode7CentreMask = ~0; CPU.NMITriggerPoint = 4; if (strcmp (ROMName, "CACOMA KNIGHT") == 0) CPU.NMITriggerPoint = 25; 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) IAPU.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 || 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) { IAPU.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; Settings.ChuckRock = strcmp (ROMName, "CHUCK ROCK") == 0; Settings.Dezaemon = strcmp (ROMName, "DEZAEMON") == 0; if (strcmp (ROMName, "RPG-TCOOL 2") == 0) Settings.Mode7CentreMask = 1023; if (strncmp (ROMId, "JG", 2) == 0 || strcmp (ROMName, "GAIA GENSOUKI 1 JPN") == 0) { IAPU.OneCycle = 13; Settings.Mode7CentreMask = 1023; } if (strcmp (ROMName, "SUPER CHASE H.Q.") == 0) Settings.Mode7CentreMask = 1023; 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; if (strncmp (ROMId, "A3R", 3) == 0) // Power Rangers Fight 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; 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 = FillRAM + 0x304a; } /* DAISENRYAKU EXPERTWW2 */ if (strcmp (ROMId, "AEVJ") == 0) { SA1.WaitAddress = SA1.Map [0x0ed18d >> MEMMAP_SHIFT] + 0xd18d; SA1.WaitByteAddress1 = FillRAM + 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 = FillRAM + 0x3020; } /* SFC SDGUNDAMGNEXT */ if (strcmp (ROMId, "ZX3J") == 0) { SA1.WaitAddress = SA1.Map [0x0087f2 >> MEMMAP_SHIFT] + 0x87f2; SA1.WaitByteAddress1 = FillRAM + 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 = FillRAM + 0x300a; SA1.WaitByteAddress2 = FillRAM + 0x300e; } /* KIRBY SUPER DELUXE US */ if (strcmp (ROMId, "AKFE") == 0) { SA1.WaitAddress = SA1.Map [0x008cb8 >> MEMMAP_SHIFT] + 0x8cb8; SA1.WaitByteAddress1 = FillRAM + 0x300a; SA1.WaitByteAddress2 = FillRAM + 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 = FillRAM + 0x3000; } /* marvelous.zip */ if (strcmp (ROMId, "AVRJ") == 0) { SA1.WaitAddress = SA1.Map [0x0085f2 >> MEMMAP_SHIFT] + 0x85f2; SA1.WaitByteAddress1 = FillRAM + 0x3024; } /* AUGUSTA3 MASTERS NEW */ if (strcmp (ROMId, "AO3J") == 0) { SA1.WaitAddress = SA1.Map [0x00dddb >> MEMMAP_SHIFT] + 0xdddb; SA1.WaitByteAddress1 = FillRAM + 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 = FillRAM + 0x37b4; } /* PGA EUROPEAN TOUR */ if (strcmp (ROMId, "AEPE") == 0) { SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700; SA1.WaitByteAddress1 = FillRAM + 0x3102; } /* PGA TOUR 96 */ if (strcmp (ROMId, "A3GE") == 0) { SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700; SA1.WaitByteAddress1 = FillRAM + 0x3102; } /* POWER RANGERS 4 */ if (strcmp (ROMId, "A4RE") == 0) { SA1.WaitAddress = SA1.Map [0x009899 >> MEMMAP_SHIFT] + 0x9899; SA1.WaitByteAddress1 = FillRAM + 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; }}// Read variable size MSB int from a filestatic long ReadInt (FILE *f, unsigned nbytes){ long v = 0; while (nbytes--) { int c = fgetc(f); if (c == EOF) return -1; v = (v << 8) | (c & 0xFF); } return (v);}#define IPS_EOF 0x00454F46lvoid CMemory::CheckForIPSPatch (const char *rom_filename, bool8 header, int32 &rom_size){ char dir [_MAX_DIR + 1]; char drive [_MAX_DRIVE + 1]; char name [_MAX_FNAME + 1]; char ext [_MAX_EXT + 1]; char fname [_MAX_PATH + 1]; FILE *patch_file = NULL; long offset = header ? 512 : 0; _splitpath (rom_filename, drive, dir, name, ext); _makepath (fname, drive, dir, name, "ips"); if (!(patch_file = fopen (fname, "rb"))) { if (!(patch_file = fopen (S9xGetFilename (".ips"), "rb"))) return; } if (fread (fname, 1, 5, patch_file) != 5 || strncmp (fname, "PATCH", 5) != 0) { fclose (patch_file); return; } int32 ofs; for (;;) { long len; long rlen; int rchar; ofs = ReadInt (patch_file, 3); if (ofs == -1) goto err_eof; if (ofs == IPS_EOF) break; ofs -= offset; len = ReadInt (patch_file, 2); if (len == -1) goto err_eof; /* Apply patch block */ if (len) { if (ofs + len > MAX_ROM_SIZE) goto err_eof; while (len--) { rchar = fgetc (patch_file); if (rchar == EOF) goto err_eof; ROM [ofs++] = (uint8) rchar; } if (ofs > rom_size) rom_size = ofs; } else { rlen = ReadInt (patch_file, 2); if (rlen == -1) goto err_eof; rchar = fgetc (patch_file); if (rchar == EOF) goto err_eof; if (ofs + rlen > MAX_ROM_SIZE) goto err_eof; while (rlen--) ROM [ofs++] = (uint8) rchar; if (ofs > rom_size) rom_size = ofs; } } // Check if ROM image needs to be truncated ofs = ReadInt (patch_file, 3); if (ofs != -1 && ofs - offset < rom_size) { // Need to truncate ROM image rom_size = ofs - offset; } fclose (patch_file); return;err_eof: if (patch_file) fclose (patch_file);}#undef INLINE#define INLINE#include "getset.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -