void HuC_LoadCD(const std::string& bios_path) { static const FileExtensionSpecStruct KnownBIOSExtensions[] = { { ".pce", gettext_noop("PC Engine ROM Image") }, { ".bin", gettext_noop("PC Engine ROM Image") }, { ".bios", gettext_noop("BIOS Image") }, { NULL, NULL } }; try { MDFNFILE fp(bios_path.c_str(), KnownBIOSExtensions, _("CD BIOS")); memset(ROMSpace, 0xFF, 262144); if(fp.size() & 512) fp.seek(512, SEEK_SET); fp.read(ROMSpace, 262144); fp.Close(); PCE_IsCD = 1; PCE_InitCD(); MDFN_printf(_("Arcade Card Emulation: %s\n"), PCE_ACEnabled ? _("Enabled") : _("Disabled")); for(int x = 0; x < 0x40; x++) { HuCPUFastMap[x] = ROMSpace; PCERead[x] = HuCRead; } for(int x = 0x68; x < 0x88; x++) { HuCPUFastMap[x] = ROMSpace; PCERead[x] = HuCRead; PCEWrite[x] = HuCRAMWrite; } PCEWrite[0x80] = HuCRAMWriteCDSpecial; // Hyper Dyne Special hack MDFNMP_AddRAM(262144, 0x68 * 8192, ROMSpace + 0x68 * 8192); if(PCE_ACEnabled) { arcade_card = new ArcadeCard(); for(int x = 0x40; x < 0x44; x++) { HuCPUFastMap[x] = NULL; PCERead[x] = ACPhysRead; PCEWrite[x] = ACPhysWrite; } } memset(SaveRAM, 0x00, 2048); memcpy(SaveRAM, BRAM_Init_String, 8); // So users don't have to manually intialize the file cabinet // in the CD BIOS screen. LoadSaveMemory(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav"), SaveRAM, 2048); PCEWrite[0xF7] = SaveRAMWrite; PCERead[0xF7] = SaveRAMRead; MDFNMP_AddRAM(2048, 0xF7 * 8192, SaveRAM); } catch(...) { Cleanup(); throw; } }
uint32 HuC_Load(MDFNFILE* fp, bool DisableBRAM, SysCardType syscard) { uint32 crc = 0; const uint32 sf2_threshold = 2048 * 1024; bool sf2_mapper = FALSE; bool mcg_mapper = FALSE; bool UseBRAM = FALSE; try { uint64 len, m_len; len = fp->size(); if(len & 512) // Skip copier header. { len &= ~512; fp->seek(512, SEEK_SET); } m_len = (len + 8191) &~ 8191; if(len >= 8192) { uint8 buf[8192]; fp->read(buf, 8192); if(!memcmp(buf + 0x1FD0, "MCGENJIN", 8)) mcg_mapper = TRUE; fp->seek(-8192, SEEK_CUR); // Seek backwards so we don't undo skip copier header. } if(!syscard && m_len >= sf2_threshold && !mcg_mapper) { sf2_mapper = TRUE; // Only used the "extended" SF2 mapper if it's considerably larger than the normal SF2 mapper size. if(m_len < (512 * 1024 * 6)) m_len = 512 * 1024 * 5; else m_len = round_up_pow2(m_len - 512 * 1024) + 512 * 1024; if(m_len > 8912896) throw MDFN_Error(0, _("ROM image is too large for extended SF2 mapper!")); HuCSF2BankMask = ((m_len - 512 * 1024) / (512 * 1024)) - 1; //printf("%d %d, %02x\n", len, m_len, HuCSF2BankMask); } IsPopulous = 0; PCE_IsCD = 0; if(syscard != SYSCARD_NONE) { CDRAM = new uint8[8 * 8192]; for(int x = 0x80; x < 0x88; x++) { ROMMap[x] = &CDRAM[(x - 0x80) * 8192] - x * 8192; HuCPU.SetFastRead(x, ROMMap[x] + x * 8192); HuCPU.SetReadHandler(x, CDRAMRead); HuCPU.SetWriteHandler(x, CDRAMWrite); } MDFNMP_AddRAM(8 * 8192, 0x80 * 8192, CDRAM); UseBRAM = TRUE; } if(mcg_mapper) { mcg = new MCGenjin(fp); for(unsigned i = 0; i < 128; i++) { HuCPU.SetFastRead(i, NULL); HuCPU.SetReadHandler(i, MCG_ReadHandler); HuCPU.SetWriteHandler(i, MCG_WriteHandler); } for(unsigned i = 0; i < mcg->GetNVPDC(); i++) { uint32 nvs = mcg->GetNVSize(i); if(nvs) { char buf[32]; std::vector<uint8> tmp_buf; tmp_buf.resize(nvs); trio_snprintf(buf, sizeof(buf), "mg%d", i); LoadSaveMemory(MDFN_MakeFName(MDFNMKF_SAV, 0, buf), &tmp_buf[0], tmp_buf.size(), false); mcg->WriteNV(i, &tmp_buf[0], 0, tmp_buf.size()); } } goto BRAM_Init; // SO EVIL YES EVVIIIIIL(FIXME) } HuCROM = new uint8[m_len]; memset(HuCROM, 0xFF, m_len); fp->read(HuCROM, std::min<uint64>(m_len, len)); crc = crc32(0, HuCROM, std::min<uint64>(m_len, len)); if(syscard == SYSCARD_NONE) { md5_context md5; md5.starts(); md5.update(HuCROM, std::min<uint64>(m_len, len)); md5.finish(MDFNGameInfo->MD5); MDFN_printf(_("ROM: %lluKiB\n"), (unsigned long long)(std::min<uint64>(m_len, len) / 1024)); MDFN_printf(_("ROM CRC32: 0x%08x\n"), crc); MDFN_printf(_("ROM MD5: 0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str()); } if(m_len == 0x60000) { for(int x = 0; x < 128; x++) { ROMMap[x] = &HuCROM[(x & 0x1F) * 8192] - x * 8192; HuCPU.SetFastRead(x, ROMMap[x] + x * 8192); HuCPU.SetReadHandler(x, HuCRead); } for(int x = 64; x < 128; x++) { ROMMap[x] = &HuCROM[((x & 0xF) + 32) * 8192] - x * 8192; HuCPU.SetFastRead(x, ROMMap[x] + x * 8192); HuCPU.SetReadHandler(x, HuCRead); } } else if(m_len == 0x80000) { for(int x = 0; x < 64; x++) { ROMMap[x] = &HuCROM[(x & 0x3F) * 8192] - x * 8192; HuCPU.SetFastRead(x, ROMMap[x] + x * 8192); HuCPU.SetReadHandler(x, HuCRead); } for(int x = 64; x < 128; x++) { ROMMap[x] = &HuCROM[((x & 0x1F) + 32) * 8192] - x * 8192; HuCPU.SetFastRead(x, ROMMap[x] + x * 8192); HuCPU.SetReadHandler(x, HuCRead); } } else { for(int x = 0; x < 128; x++) { uint8 bank = x % (m_len / 8192); ROMMap[x] = &HuCROM[bank * 8192] - x * 8192; HuCPU.SetFastRead(x, ROMMap[x] + x * 8192); HuCPU.SetReadHandler(x, HuCRead); } } if(syscard) { if(syscard == SYSCARD_3 || syscard == SYSCARD_ARCADE) { SysCardRAM = new uint8[24 * 8192]; for(int x = 0x68; x < 0x80; x++) { ROMMap[x] = &SysCardRAM[(x - 0x68) * 8192] - x * 8192; HuCPU.SetFastRead(x, ROMMap[x] + x * 8192); HuCPU.SetReadHandler(x, SysCardRAMRead); HuCPU.SetWriteHandler(x, SysCardRAMWrite); } MDFNMP_AddRAM(24 * 8192, 0x68 * 8192, SysCardRAM); } if(syscard == SYSCARD_ARCADE) { arcade_card = new ArcadeCard(); for(int x = 0x40; x < 0x44; x++) { ROMMap[x] = NULL; HuCPU.SetFastRead(x, NULL); HuCPU.SetReadHandler(x, AC_PhysRead); HuCPU.SetWriteHandler(x, AC_PhysWrite); } } } else { if(!memcmp(HuCROM + 0x1F26, "POPULOUS", strlen("POPULOUS"))) { PopRAM = new uint8[32768]; memset(PopRAM, 0xFF, 32768); LoadSaveMemory(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav"), PopRAM, 32768); IsPopulous = 1; MDFN_printf("Populous\n"); for(int x = 0x40; x < 0x44; x++) { ROMMap[x] = &PopRAM[(x & 3) * 8192] - x * 8192; HuCPU.SetFastRead(x, ROMMap[x] + x * 8192); HuCPU.SetReadHandler(x, HuCRead); HuCPU.SetWriteHandler(x, HuCRAMWrite); } MDFNMP_AddRAM(32768, 0x40 * 8192, PopRAM); } else if(crc == 0x34dc65c4) // Tsushin Booster { TsushinRAM = new uint8[0x8000]; memset(TsushinRAM, 0xFF, 0x8000); LoadSaveMemory(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav"), TsushinRAM, 32768); IsTsushin = 1; MDFN_printf("Tsushin Booster\n"); for(int x = 0x88; x < 0x8C; x++) { ROMMap[x] = &TsushinRAM[(x & 3) * 8192] - x * 8192; HuCPU.SetFastRead(x, ROMMap[x] + x * 8192); HuCPU.SetReadHandler(x, HuCRead); HuCPU.SetWriteHandler(x, HuCRAMWrite); } MDFNMP_AddRAM(32768, 0x88 * 8192, TsushinRAM); } else UseBRAM = TRUE; // 0x1A558 if(sf2_mapper) { for(int x = 0x20; x < 0x40; x++) HuCPU.SetReadHandler(x, HuCSF2ReadLow); for(int x = 0x40; x < 0x80; x++) { HuCPU.SetFastRead(x, NULL); // Make sure our reads go through our read function, and not a table lookup HuCPU.SetReadHandler(x, HuCSF2Read); } HuCPU.SetWriteHandler(0, HuCSF2Write); MDFN_printf("Street Fighter 2 Mapper\n"); HuCSF2Latch = 0; } } // end else to if(syscard) BRAM_Init: BRAM_Disabled = DisableBRAM; if(BRAM_Disabled) UseBRAM = false; if(UseBRAM) { // Initialize BRAM here so users don't have to manually intialize the file cabinet // in the CD BIOS screen. memset(SaveRAM, 0x00, 2048); memcpy(SaveRAM, BRAM_Init_String, 8); LoadSaveMemory(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav"), SaveRAM, 2048); HuCPU.SetWriteHandler(0xF7, SaveRAMWrite); HuCPU.SetReadHandler(0xF7, SaveRAMRead); MDFNMP_AddRAM(2048, 0xF7 * 8192, SaveRAM); } } catch(...) { Cleanup(); throw; } return crc; }
uint32 HuC_Load(MDFNFILE* fp) { uint32 crc = 0; try { uint32 sf2_threshold = 2048 * 1024; uint32 sf2_required_size = 2048 * 1024 + 512 * 1024; uint64 len = fp->size(); uint64 m_len = (len + 8191)&~8191; bool sf2_mapper = FALSE; if(m_len >= sf2_threshold) { sf2_mapper = TRUE; if(m_len != sf2_required_size) m_len = sf2_required_size; } IsPopulous = 0; PCE_IsCD = 0; HuCROM = (uint8 *)MDFN_malloc_T(m_len, _("HuCard ROM")); memset(HuCROM, 0xFF, m_len); fp->read(HuCROM, std::min<uint64>(m_len, len)); md5_context md5; md5.starts(); md5.update(HuCROM, std::min<uint64>(m_len, len)); md5.finish(MDFNGameInfo->MD5); crc = crc32(0, HuCROM, std::min<uint64>(m_len, len)); MDFN_printf(_("ROM: %lluKiB\n"), (unsigned long long)(std::min<uint64>(m_len, len) / 1024)); MDFN_printf(_("ROM CRC32: 0x%04x\n"), crc); MDFN_printf(_("ROM MD5: 0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str()); memset(ROMSpace, 0xFF, 0x88 * 8192 + 8192); if(m_len == 0x60000) { memcpy(ROMSpace + 0x00 * 8192, HuCROM, 0x20 * 8192); memcpy(ROMSpace + 0x20 * 8192, HuCROM, 0x20 * 8192); memcpy(ROMSpace + 0x40 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192); memcpy(ROMSpace + 0x50 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192); memcpy(ROMSpace + 0x60 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192); memcpy(ROMSpace + 0x70 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192); } else if(m_len == 0x80000) { memcpy(ROMSpace + 0x00 * 8192, HuCROM, 0x40 * 8192); memcpy(ROMSpace + 0x40 * 8192, HuCROM + 0x20 * 8192, 0x20 * 8192); memcpy(ROMSpace + 0x60 * 8192, HuCROM + 0x20 * 8192, 0x20 * 8192); } else { memcpy(ROMSpace + 0x00 * 8192, HuCROM, (m_len < 1024 * 1024) ? m_len : 1024 * 1024); } for(int x = 0x00; x < 0x80; x++) { HuCPUFastMap[x] = ROMSpace; PCERead[x] = HuCRead; } if(!memcmp(HuCROM + 0x1F26, "POPULOUS", strlen("POPULOUS"))) { uint8 *PopRAM = ROMSpace + 0x40 * 8192; memset(PopRAM, 0xFF, 32768); LoadSaveMemory(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav"), PopRAM, 32768); IsPopulous = 1; MDFN_printf("Populous\n"); for(int x = 0x40; x < 0x44; x++) { HuCPUFastMap[x] = &PopRAM[(x & 3) * 8192] - x * 8192; PCERead[x] = HuCRead; PCEWrite[x] = HuCRAMWrite; } MDFNMP_AddRAM(32768, 0x40 * 8192, PopRAM); } else { memset(SaveRAM, 0x00, 2048); memcpy(SaveRAM, BRAM_Init_String, 8); // So users don't have to manually intialize the file cabinet // in the CD BIOS screen. LoadSaveMemory(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav"), SaveRAM, 2048); PCEWrite[0xF7] = SaveRAMWrite; PCERead[0xF7] = SaveRAMRead; MDFNMP_AddRAM(2048, 0xF7 * 8192, SaveRAM); } // 0x1A558 //if(len >= 0x20000 && !memcmp(HuCROM + 0x1A558, "STREET FIGHTER#", strlen("STREET FIGHTER#"))) if(sf2_mapper) { for(int x = 0x40; x < 0x80; x++) { // FIXME: PCE_FAST HuCPUFastMap[x] = NULL; // Make sure our reads go through our read function, and not a table lookup PCERead[x] = HuCSF2Read; } PCEWrite[0] = HuCSF2Write; MDFN_printf("Street Fighter 2 Mapper\n"); HuCSF2Latch = 0; } } catch(...) { Cleanup(); throw; } return crc; }