Ejemplo n.º 1
0
int
ucon64_rom_handling (void)
{
  int no_rom = 0;
  static st_rominfo_t rominfo;
  struct stat fstate;

  ucon64_rom_flush (&rominfo);

  // a ROM (file)?
  if (!ucon64.rom)
    no_rom = 1;
  else if (!ucon64.rom[0])
    no_rom = 1;
  else if (access (ucon64.rom, F_OK | R_OK) == -1 && (!(ucon64.flags & WF_NO_ROM)))
    {
      fprintf (stderr, "ERROR: Could not open %s\n", ucon64.rom);
      no_rom = 1;
    }
  else if (stat (ucon64.rom, &fstate) == -1)
    no_rom = 1;
  else if (S_ISREG (fstate.st_mode) != TRUE)
    no_rom = 1;
#if 0
  // printing the no_rom error message for files of 0 bytes only confuses people
  else if (!fstate.st_size)
    no_rom = 1;
#endif

  if (no_rom)
    {
      if (!(ucon64.flags & WF_NO_ROM))
        {
          fputs ("ERROR: This option requires a file argument (ROM/image/SRAM file/directory)\n", stderr);
          return -1;
        }
      return 0;
    }

  // The next statement is important and should be executed as soon as
  //  possible (and sensible) in this function
  ucon64.file_size = fsizeof (ucon64.rom);
  // We have to do this here, because we don't know the file size until now
  if (ucon64.buheader_len > ucon64.file_size)
    {
      fprintf (stderr,
               "ERROR: A backup unit header length was specified that is larger than the file\n"
               "       size (%d > %d)\n", ucon64.buheader_len, ucon64.file_size);
      return -1;
    }

  if (!(ucon64.flags & WF_INIT))
    return 0;

  // "walk through" <console>_init()
  if (ucon64.flags & WF_PROBE)
    {
      if (ucon64.rominfo)
        {
          // Restore any overrides from st_ucon64_t
          // We have to do this *before* calling ucon64_probe(), *not* afterwards
          if (UCON64_ISSET (ucon64.buheader_len))
            rominfo.buheader_len = ucon64.buheader_len;

          if (UCON64_ISSET (ucon64.interleaved))
            rominfo.interleaved = ucon64.interleaved;

//          ucon64.rominfo = (st_rominfo_t *) &rominfo;
        }
      ucon64.rominfo = ucon64_probe (&rominfo); // determines console type

#ifdef  USE_DISCMAGE
      // check for disc image only if ucon64_probe() failed or --disc was used
      if (ucon64.discmage_enabled)
//        if (!ucon64.rominfo || ucon64.force_disc)
        if (ucon64.force_disc)
          ucon64.image = dm_reopen (ucon64.rom, 0, (dm_image_t *) ucon64.image);
#endif
    }
  // end of WF_PROBE

  // Does the option allow split ROMs?
  if (ucon64.flags & WF_NO_SPLIT)
    /*
      Test for split files only if the console type knows about split files at
      all. However we only know the console type after probing.
    */
    if (ucon64.console == UCON64_NES || ucon64.console == UCON64_SNES ||
        ucon64.console == UCON64_GEN || ucon64.console == UCON64_NG)
      if ((UCON64_ISSET (ucon64.split)) ? ucon64.split : ucon64_testsplit (ucon64.rom))
        {
          fprintf (stderr, "ERROR: %s seems to be split. You have to join it first\n",
                   basename2 (ucon64.rom));
          return -1;
        }


  /*
    CRC32

    Calculating the CRC32 checksum for the ROM data of a UNIF file (NES)
    shouldn't be done with ucon64_fcrc32(). nes_init() uses crc32().
    The CRC32 checksum is used to search in the DAT files, but at the time
    of this writing (Februari the 7th 2003) all DAT files contain checksums
    of files in only one format. This matters for SNES and Genesis ROMs in
    interleaved format and Nintendo 64 ROMs in non-interleaved format. The
    corresponding initialization functions calculate the CRC32 checksum of
    the data in the format of which the checksum is stored in the DAT
    files. For these "problematic" files, their "real" checksum is stored
    in ucon64.fcrc32.
  */
  if (ucon64.crc32 == 0)
    if (!ucon64.force_disc) // NOT for disc images
      if (!(ucon64.flags & WF_NO_CRC32) && ucon64.file_size <= MAXROMSIZE)
        ucon64_chksum (NULL, NULL, &ucon64.crc32, ucon64.rom, ucon64.rominfo ? ucon64.rominfo->buheader_len : 0);


  // DATabase
  ucon64.dat = NULL;
  if (ucon64.crc32 != 0 && ucon64.dat_enabled)
    {
      ucon64.dat = ucon64_dat_search (ucon64.crc32, NULL);
      if (ucon64.dat)
        {
          // detected file size must match DAT file size
          int size = ucon64.rominfo ?
                       UCON64_ISSET (ucon64.rominfo->data_size) ?
                         ucon64.rominfo->data_size :
                         ucon64.file_size - ucon64.rominfo->buheader_len :
                       ucon64.file_size;
          if ((int) (((st_ucon64_dat_t *) ucon64.dat)->fsize) != size)
            ucon64.dat = NULL;
        }

      if (ucon64.dat)
        switch (ucon64.console)
          {
            case UCON64_SNES:
            case UCON64_GEN:
            case UCON64_GB:
            case UCON64_GBA:
            case UCON64_N64:
              // These ROMs have internal headers with name, country, maker, etc.
              break;

            default:
              // Use ucon64.dat instead of ucon64.dat_enabled in case the index
              //  file could not be created/opened -> no segmentation fault
              if (ucon64.dat && ucon64.rominfo)
                {
                  if (!ucon64.rominfo->name[0])
                    strcpy (ucon64.rominfo->name, NULL_TO_EMPTY (((st_ucon64_dat_t *) ucon64.dat)->name));
                  else if (ucon64.console == UCON64_NES)
                    { // override the three-character FDS or FAM name
                      int t = nes_get_file_type ();
                      if (t == FDS || t == FAM)
                        strcpy (ucon64.rominfo->name, NULL_TO_EMPTY (((st_ucon64_dat_t *) ucon64.dat)->name));
                    }

                  if (!ucon64.rominfo->country)
                    ucon64.rominfo->country = NULL_TO_EMPTY (((st_ucon64_dat_t *) ucon64.dat)->country);
                }
              break;
          }
    }

  // display info
  if ((ucon64.flags & WF_NFO || ucon64.flags & WF_NFO_AFTER) && ucon64.quiet < 1)
    ucon64_nfo ();

  return 0;
}
Ejemplo n.º 2
0
int
atari_init (st_ucon64_nfo_t * rominfo)
{
  int i, j, bsmode, size = ucon64.file_size;
  unsigned int crc32;
  static char backup_usage[80];
  unsigned char first, image[ATARI_ROM_SIZE], buffer[0x200];
  char md5[32];

  if (size > ATARI_ROM_SIZE)
    return -1;

  if (size != 0x800  && size != 0x1000  && size != 0x2000 && size != 0x2100 &&
      size != 0x2800 && size != 0x28ff  && size != 0x3000 && size != 0x4000 &&
      size != 0x8000 && size != 0x10000 && size != 0x20000)
    return -1;

  ucon64_fread (image, 0, size, ucon64.fname);
  ucon64_chksum (NULL, md5, &crc32, ucon64.fname, ucon64.file_size, 0);

  bsmode = get_game_bsmode_by_crc (crc32);
  if (bsmode == -1)
    bsmode = get_game_bsmode_by_md5 (md5);

  if (bsmode == -1)
    {
      if (!(size % 8448))
        bsmode = BSM_AR;
      else if (size == 2048 || !memcmp (image, image + 2048, 2048))
        bsmode = BSM_2K;
      else if (size == 4096 || !memcmp (image, image + 4096, 4096))
        bsmode = BSM_4K;
      else if (size == 8192 || !memcmp (image, image + 8192, 8192))
        bsmode = is_probably_3f (image, size) ? BSM_3F : BSM_F8;
      else if (size == 10495 || (size == 10240))
        bsmode = BSM_DPC;
      else if (size == 12288)
        bsmode = BSM_FASC;
      else if (size == 32768)
        {
          // Assume this is a 32K super-cart then check to see if it is
          bsmode = BSM_F4SC;

          first = image[0];
          for (i = 0; i < 0x100; i++)
            if (image[i] != first)
              {
                // It's not a super cart (probably)
                bsmode = is_probably_3f (image, size) ? BSM_3F : BSM_F4;
                break;
              }
        }
      else if (size == 65536)
        bsmode = is_probably_3f (image, size) ? BSM_3F : BSM_MB;
      else if (size == 131072)
        bsmode = is_probably_3f (image, size) ? BSM_3F : BSM_MC;
      else
        {
          // Assume this is a 16K super-cart then check to see if it is
          bsmode = BSM_F6SC;

          first = image[0];
          for (i = 0; i < 0x100; i++)
            if (image[i] != first)
              {
                // It's not a super cart (probably)
                bsmode = is_probably_3f (image, size) ? BSM_3F : BSM_F6;
                break;
              }
        }
    }

  if (bsmode > 0)
    {
      memset (&atari_rominfo, 0, sizeof (st_atari_rominfo_t));

      atari_rominfo.bsm = bsmode;

      // set game_page_count and empty_page[]
      for (i = 0; i < size / 0x100; i++)
        {
          ucon64_fread (buffer, i * 0x100, 0x100, ucon64.fname);
          atari_rominfo.empty_page[i] = 1;

          for (j = 0; j < 0x100 - 1; j++)
            if (buffer[j] != buffer[j + 1])
              {
                atari_rominfo.empty_page[i] = 0;
                atari_rominfo.game_page_count++;
                break;
              }
        }

      atari_rominfo.speed_hi = (unsigned char) (atari_rominfo.game_page_count / 21 + 1);
      atari_rominfo.speed_low = (unsigned char) (atari_rominfo.game_page_count * 0x100 / 21 - (atari_rominfo.speed_hi - 1) * 0x100);

      atari_rominfo.ctrl_byte = get_bsmode_by_id (atari_rominfo.bsm)->ctrl_byte;

      // the first two bytes of data indicate the beginning address of the code
      if (atari_rominfo.bsm != BSM_3F)
        {
          ucon64_fread (buffer, get_bsmode_by_id (atari_rominfo.bsm)->start_page * 0x100, 0x100, ucon64.fname);
          atari_rominfo.start_low = buffer[0xfc];
          atari_rominfo.start_hi = buffer[0xfd];
        }

      rominfo->console_usage = atari_usage[0].help;
      // "Cuttle Card (2)/Starpath) Supercharger/YOKO backup unit"
      snprintf (backup_usage, 80, "%s/%s/%s", cc2_usage[0].help,
                spsc_usage[0].help, yoko_usage[0].help);
      backup_usage[80 - 1] = 0;
      rominfo->backup_usage = backup_usage;

      sprintf (rominfo->misc,
               "Bankswitch type: %s\n"
               "Start address: 0x%02x%02x\n"
               "Speed: 0x%02x%02x\n"
               "Control byte: 0x%02x\n"
               "Page count: %d\n"
               "Blank pages: %d\n"
               "Start page: %d",
               get_bsmode_by_id (atari_rominfo.bsm)->bsm_s,
               atari_rominfo.start_hi,
               atari_rominfo.start_low,
               atari_rominfo.speed_hi,
               atari_rominfo.speed_low,
               atari_rominfo.ctrl_byte,
               atari_rominfo.game_page_count,
               size / 0x100 - atari_rominfo.game_page_count,
               get_bsmode_by_id (atari_rominfo.bsm)->start_page);
      return 0;
    }

  return -1;
}