void MDCart_Load(md_game_info *ginfo, MDFNFILE *fp) { try { const char *mapper = NULL; const uint64 fp_in_size = fp->size(); if(fp_in_size < 0x200) throw MDFN_Error(0, _("ROM image is too small.")); if(fp_in_size > 1024 * 1024 * 128) throw MDFN_Error(0, _("ROM image is too large.")); Cart_ROM_Size = fp_in_size; cart_rom = (uint8 *)MDFN_calloc_T(1, Cart_ROM_Size, _("Cart ROM")); fp->read(cart_rom, Cart_ROM_Size); MD_ReadSegaHeader(cart_rom + 0x100, ginfo); ginfo->rom_size = Cart_ROM_Size; md5_context md5; md5.starts(); md5.update(cart_rom, Cart_ROM_Size); md5.finish(ginfo->md5); ginfo->crc32 = crc32(0, cart_rom, Cart_ROM_Size); md5.starts(); md5.update(cart_rom + 0x100, 0x100); md5.finish(ginfo->info_header_md5); ginfo->checksum_real = 0; for(uint32 i = 0x200; i < Cart_ROM_Size; i += 2) { ginfo->checksum_real += cart_rom[i + 0] << 8; ginfo->checksum_real += cart_rom[i + 1] << 0; } // Rockman MegaWorld: 5241e840 // Sonic 3: 5241f820 uint32 sram_type = MDFN_de32msb(&cart_rom[0x1B0]); uint32 sram_start = MDFN_de32msb(&cart_rom[0x1B4]); uint32 sram_end = MDFN_de32msb(&cart_rom[0x1B8]); { uint64 hmd5_partial = 0; uint64 md5_partial = 0; for(int i = 0; i < 8; i++) { hmd5_partial |= (uint64)ginfo->info_header_md5[15 - i] << (8 * i); md5_partial |= (uint64)ginfo->md5[15 - i] << (8 * i); } //printf("Real: 0x%016llxULL Header: 0x%016llxULL\n", (unsigned long long)md5_partial, (unsigned long long)hmd5_partial); for(unsigned int i = 0; i < sizeof(GamesDB) / sizeof(game_db_t); i++) { bool found = true; if(GamesDB[i].header_md5 && GamesDB[i].header_md5 != hmd5_partial) found = false; if(GamesDB[i].md5 && GamesDB[i].md5 != md5_partial) found = false; if(GamesDB[i].id && strcmp(GamesDB[i].id, ginfo->product_code)) found = false; if(found) { if(GamesDB[i].mapper) mapper = GamesDB[i].mapper; if(GamesDB[i].sram_type != ~0U) sram_type = GamesDB[i].sram_type; if(GamesDB[i].sram_start > 0) sram_start = GamesDB[i].sram_start; if(GamesDB[i].sram_end > 0) sram_end = GamesDB[i].sram_end; if(GamesDB[i].region_support > 0) ginfo->region_support = GamesDB[i].region_support; break; } } } if(sram_type == 0x5241f820 && sram_start == 0x20202020) sram_type = 0x20202020; ginfo->sram_type = sram_type; ginfo->sram_start = sram_start; ginfo->sram_end = sram_end; if(!mapper) { if(sram_type == 0x5241f820) mapper = "SRAM"; else if(sram_type == 0x5241e840) mapper = "Sega_24C01"; else mapper = "ROM"; } { const BoardHandler_t *bh = BoardHandlers; bool BoardFound = FALSE; MDFN_printf(_("Mapper: %s\n"), mapper); MDFN_printf(_("SRAM Type: 0x%08x\n"), sram_type); MDFN_printf(_("SRAM Start: 0x%08x\n"), sram_start); MDFN_printf(_("SRAM End: 0x%08x\n"), sram_end); while(bh->boardname) { if(!strcasecmp(bh->boardname, mapper)) { cart_hardware = bh->MapperMake(ginfo, cart_rom, Cart_ROM_Size, bh->iparam, bh->sparam); BoardFound = TRUE; break; } bh++; } if(!BoardFound) { throw MDFN_Error(0, _("Handler for mapper/board \"%s\" not found!\n"), mapper); } } //MD_Cart_Type* (*MapperMake)(const md_game_info *ginfo, const uint8 *ROM, const uint32 ROM_size) = NULL; //cart_hardware = MapperMake(ginfo, cart_rom, Cart_ROM_Size); } catch(...) { Cleanup(); throw; } }
void HuC_Load(const uint8 *data, uint32 len, uint32 crc32, bool DisableBRAM, SysCardType syscard) { const uint32 sf2_threshold = 2048 * 1024; uint32 m_len = (len + 8191) &~ 8191; bool sf2_mapper = FALSE; bool mcg_mapper = FALSE; bool UseBRAM = FALSE; // // Obvious, but anyway: catch exceptions and free any allocated memory here, otherwise when code higher up calls HuC_Close(), it might wipe out save game files. // try { if(len >= 8192 && !memcmp(data + 0x1FD0, "MCGENJIN", 8)) mcg_mapper = TRUE; 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) { md5_context md5; md5.starts(); md5.update(data, len); md5.finish(MDFNGameInfo->MD5); MDFN_printf(_("ROM: %dKiB\n"), (len + 1023) / 1024); MDFN_printf(_("ROM CRC32: 0x%08x\n"), crc32); MDFN_printf(_("ROM MD5: 0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str()); } if(syscard != SYSCARD_NONE) { CDRAM = (uint8 *)MDFN_calloc_T(1, 8 * 8192, _("CD RAM")); 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(data, len); for(unsigned i = 0; i < 128; i++) { HuCPU->SetFastRead(i, NULL); HuCPU->SetReadHandler(i, MCG_ReadHandler); HuCPU->SetWriteHandler(i, MCG_WriteHandler); } goto BRAM_Init; // SO EVIL YES EVVIIIIIL(FIXME) } HuCROM = (uint8 *)MDFN_malloc_T(m_len, _("HuCard ROM")); memset(HuCROM, 0xFF, m_len); memcpy(HuCROM, data, (m_len < len) ? m_len : len); 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 = (uint8 *)MDFN_calloc_T(1, 24 * 8192, _("System Card RAM")); 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"))) { gzFile fp; PopRAM = (uint8 *)MDFN_malloc_T(32768, _("Populous RAM")); memset(PopRAM, 0xFF, 32768); if((fp = gzopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb"))) { gzread(fp, PopRAM, 32768); gzclose(fp); } 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(crc32 == 0x34dc65c4) // Tsushin Booster { gzFile fp; TsushinRAM = (uint8*)MDFN_malloc_T(0x8000, _("Tsushin Booster RAM")); memset(TsushinRAM, 0xFF, 0x8000); if((fp = gzopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb"))) { gzread(fp, TsushinRAM, 32768); gzclose(fp); } 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) { gzFile fp; 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. if((fp = gzopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb"))) { gzread(fp, SaveRAM, 2048); gzclose(fp); } HuCPU->SetWriteHandler(0xF7, SaveRAMWrite); HuCPU->SetReadHandler(0xF7, SaveRAMRead); MDFNMP_AddRAM(2048, 0xF7 * 8192, SaveRAM); } } catch(...) { Cleanup(); throw; } }