Beispiel #1
0
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;
 }
}
Beispiel #2
0
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;
 }
}