int load_rom()

in cores/genesis/core/loadrom.c [530:978]


int load_rom(char *filename)
{
  int i, size;

#ifdef USE_DYNAMIC_ALLOC
  if (!ext)
  {
    /* allocate & initialize memory for Cartridge / CD hardware if required */
    ext = (external_t *)calloc(1, sizeof(external_t));
    if (!ext) return (0);
  }
#endif

  /* clear any existing patches */
  ggenie_shutdown();
  areplay_shutdown();

  /* check previous loaded ROM size */
  if (cart.romsize > 0x800000)
  {
    /* assume no CD is currently loaded */
    cdd.loaded = 0;
  }

  /* auto-detect CD image file */
  size = cdd_load(filename, (char *)(cart.rom));
  if (size < 0)
  {
    /* error opening file */
    return (0);
  }

  /* CD image file ? */
  if (size)
  {
    /* enable CD hardware */
    system_hw = SYSTEM_MCD;

    /* boot from CD hardware */
    scd.cartridge.boot = 0x00;
  }
  else
  {
    /* load file into ROM buffer */
    char extension[4];
    size = load_archive(filename, cart.rom, cdd.loaded ? 0x800000 : MAXROMSIZE, extension);

    /* mark BOOTROM as unloaded if they have been overwritten by cartridge ROM */
    if (size > 0x800000)
    {
      /* CD BIOS ROM are loaded at the start of CD area */
      system_bios &= ~0x10;
    }
    else if (size > 0x400000)
    {
      /* Master System or Game Gear BIOS ROM are loaded within $400000-$4FFFFF area */
      system_bios &= ~(SYSTEM_SMS | SYSTEM_GG);
    }
    else if (size <= 0)
    {
      /* mark all BOOTROM as unloaded since they could have been overwritten */
      system_bios &= ~(0x10 | SYSTEM_SMS | SYSTEM_GG);
      
      /* error loading file */
      return 0;
    }

    /* convert lower case file extension to upper case */
    *(uint32 *)(extension) &= 0xdfdfdfdf;

    /* auto-detect system hardware from ROM file extension */
    if (!memcmp("SMS", &extension[0], 3))
    {
      /* Master System II hardware */
      system_hw = SYSTEM_SMS2;
    }
    else if (!memcmp("GG", &extension[1], 2))
    {
      /* Game Gear hardware (GG mode) */
      system_hw = SYSTEM_GG;
    }
    else if (!memcmp("SG", &extension[1], 2))
    {
      /* SG-1000 hardware */
      system_hw = SYSTEM_SG;
    }
    else
    {
      /* default is Mega Drive / Genesis hardware (16-bit mode) */
      system_hw = SYSTEM_MD;

      /* decode .MDX format */
      if (!memcmp("MDX", &extension[0], 3))
      {
        for (i = 4; i < size - 1; i++)
        {
          cart.rom[i-4] = cart.rom[i] ^ 0x40;
        }
        size = size - 5;
      }

      /* auto-detect byte-swapped dumps */
      if (!memcmp((char *)(cart.rom + 0x100),"ESAGM GE ARDVI E", 16) ||
          !memcmp((char *)(cart.rom + 0x100),"ESAGG NESESI", 12))
      {
        for(i = 0; i < size; i += 2)
        {
          uint8 temp = cart.rom[i];
          cart.rom[i] = cart.rom[i+1];
          cart.rom[i+1] = temp;
        }
      }
    }

    /* auto-detect 512 byte extra header */
    if (memcmp((char *)(cart.rom + 0x100), "SEGA", 4) && ((size / 512) & 1) && !(size % 512))
    {
      /* remove header */
      size -= 512;
      memmove (cart.rom, cart.rom + 512, size);

      /* assume interleaved Mega Drive / Genesis ROM format (.smd) */
      if (system_hw == SYSTEM_MD)
      {
        for (i = 0; i < (size / 0x4000); i++)
        {
          deinterleave_block (cart.rom + (i * 0x4000));
        }
      }
    }
  }
    
  /* initialize ROM size */
  cart.romsize = size;

  /* get infos from ROM header */
  getrominfo((char *)(cart.rom));

  /* set console region */
  get_region((char *)(cart.rom));

#ifdef LSB_FIRST
  /* 16-bit ROM specific */
  if (system_hw == SYSTEM_MD)
  {
    /* Byteswap ROM to optimize 16-bit access */
    for (i = 0; i < cart.romsize; i += 2)
    {
      uint8 temp = cart.rom[i];
      cart.rom[i] = cart.rom[i+1];
      cart.rom[i+1] = temp;
    }
  }
#endif

  /* PICO ROM */
  if (strstr(rominfo.consoletype, "SEGA PICO") != NULL)
  {
    /* PICO hardware */
    system_hw = SYSTEM_PICO;
  }

  /* Save auto-detected system hardware  */
  romtype = system_hw;
  
  /* CD image file */
  if (system_hw == SYSTEM_MCD)
  {   
    /* try to load CD BOOTROM for selected region */
    if (!load_bios(SYSTEM_MCD))
    {
      /* unmount CD image */
      cdd_unload();

      /* error booting from CD */
      return (0);
    }
  }

  /* CD BOOTROM */
  else if (strstr(rominfo.ROMType, "BR") != NULL)
  {
    /* enable CD hardware */
    system_hw = SYSTEM_MCD;

    /* boot from CD hardware */
    scd.cartridge.boot = 0x00;

    /* copy ROM to BOOTROM area */
    memcpy(scd.bootrom, cart.rom, sizeof(scd.bootrom));

    /* mark CD BIOS as being loaded */
    system_bios = system_bios | 0x10;

    /* loaded CD BIOS region */
    system_bios = (system_bios & 0xf0) | (region_code >> 4);
  }

  /* ROM cartridge (max. 8MB) with CD loaded */
  else if ((cart.romsize <= 0x800000) && cdd.loaded)
  {
    /* try to load CD BOOTROM */
    if (load_bios(SYSTEM_MCD))
    {
      /* enable CD hardware */
      system_hw = SYSTEM_MCD;

      /* boot from cartridge */
      scd.cartridge.boot = 0x40;
    }
    else
    {
      /* unmount CD image */
      cdd_unload();
    }    
  }
  
  /* ROM cartridge with CD support */
  else if ((strstr(rominfo.domestic,"FLUX") != NULL) ||
           (strstr(rominfo.domestic,"WONDER LIBRARY") != NULL) ||
           (strstr(rominfo.product,"T-5740") != NULL))
  {
    /* check if console hardware is set to AUTO */
    if (!config.system)
    {
      /* try to load CD BOOTROM */
      if (load_bios(SYSTEM_MCD))
      {
        char fname[256];
        int len = strlen(filename);

        /* automatically try to load associated .iso file */
        while ((len && (filename[len] != '.')) || (len > 251)) len--;
        strncpy(fname, filename, len);
        strcpy(&fname[len], ".iso");
        cdd_load(fname, (char *)cdc.ram);

        /* enable CD hardware */
        system_hw = SYSTEM_MCD;

        /* boot from cartridge */
        scd.cartridge.boot = 0x40;
      }
    }
  }

  /* Force system hardware if requested */
  if (config.system == SYSTEM_MD)
  {
    if (!(system_hw & SYSTEM_MD))
    {
      /* Mega Drive in MS compatibility mode  */
      system_hw = SYSTEM_PBC;
    }
  }
  else if (config.system == SYSTEM_GG)
  {
    if (system_hw != SYSTEM_GG)
    {
      /* Game Gear in MS compatibility mode  */
      system_hw = SYSTEM_GGMS;
    }
  }
  else if (config.system)
  {
    system_hw = config.system;
  }

  /* restore previous input settings */
  if (old_system[0] != -1)
  {
    input.system[0] = old_system[0];
  }
  if (old_system[1] != -1)
  {
    input.system[1] = old_system[1];
  }

  /* default gun settings */
  input.x_offset = (input.system[1] == SYSTEM_MENACER) ? 64 : 0;
  input.y_offset = 0;

  /* autodetect gun support */
  if (strstr(rominfo.international,"MENACER") != NULL)
  {
    /* save current setting */
    if (old_system[0] == -1)
    {
      old_system[0] = input.system[0];
    }
    if (old_system[1] == -1)
    {
      old_system[1] = input.system[1];
    }

    /* force MENACER configuration */
    input.system[0] = SYSTEM_GAMEPAD;
    input.system[1] = SYSTEM_MENACER;
    input.x_offset = 82;
    input.y_offset = 0;
  }
  else if (strstr(rominfo.international,"T2 ; THE ARCADE GAME") != NULL)
  {
    /* save current setting */
    if (old_system[0] == -1)
    {
      old_system[0] = input.system[0];
    }
    if (old_system[1] == -1)
    {
      old_system[1] = input.system[1];
    }

    /* force MENACER configuration */
    input.system[0] = SYSTEM_GAMEPAD;
    input.system[1] = SYSTEM_MENACER;
    input.x_offset = 133;
    input.y_offset = -8;
  }
  else if (strstr(rominfo.international,"BODY COUNT") != NULL)
  {
    /* save current setting */
    if (old_system[0] == -1)
    {
      old_system[0] = input.system[0];
    }
    if (old_system[1] == -1)
    {
      old_system[1] = input.system[1];
    }

    /* force MENACER configuration */
    input.system[0] = SYSTEM_GAMEPAD;
    input.system[1] = SYSTEM_MENACER;
    input.x_offset = 68;
    input.y_offset = -24;
  }
  else if (strstr(rominfo.international,"CORPSE KILLER") != NULL)
  {
    /* save current setting */
    if (old_system[0] == -1)
    {
      old_system[0] = input.system[0];
    }
    if (old_system[1] == -1)
    {
      old_system[1] = input.system[1];
    }

    /* force MENACER configuration */
    input.system[0] = SYSTEM_GAMEPAD;
    input.system[1] = SYSTEM_MENACER;
    input.x_offset = 64;
    input.y_offset = -8;
  }
  else if (strstr(rominfo.international,"CRIME PATROL") != NULL)
  {
    /* save current setting */
    if (old_system[0] == -1)
    {
      old_system[0] = input.system[0];
    }
    if (old_system[1] == -1)
    {
      old_system[1] = input.system[1];
    }

    /* force MENACER configuration */
    input.system[0] = SYSTEM_GAMEPAD;
    input.system[1] = SYSTEM_MENACER;
    input.x_offset = 61;
    input.y_offset = 0;
  }
  else if (strstr(rominfo.international,"MAD DOG II THE LOST GOLD") != NULL)
  {
    /* save current setting */
    if (old_system[0] == -1)
    {
      old_system[0] = input.system[0];
    }
    if (old_system[1] == -1)
    {
      old_system[1] = input.system[1];
    }

    /* force MENACER configuration */
    input.system[0] = SYSTEM_GAMEPAD;
    input.system[1] = SYSTEM_MENACER;
    input.x_offset = 70;
    input.y_offset = 18;
  }
  else if (strstr(rominfo.international,"MAD DOG MCCREE") != NULL)
  {
    /* save current setting */
    if (old_system[0] == -1)
    {
      old_system[0] = input.system[0];
    }
    if (old_system[1] == -1)
    {
      old_system[1] = input.system[1];
    }

    /* force MENACER configuration */
    input.system[0] = SYSTEM_GAMEPAD;
    input.system[1] = SYSTEM_MENACER;
    input.x_offset = 49;
    input.y_offset = 0;
  }
  else if (strstr(rominfo.international,"WHO SHOT JOHNNY ROCK?") != NULL)
  {
    /* save current setting */
    if (old_system[0] == -1)
    {
      old_system[0] = input.system[0];
    }
    if (old_system[1] == -1)
    {
      old_system[1] = input.system[1];
    }

    /* force MENACER configuration */
    input.system[0] = SYSTEM_GAMEPAD;
    input.system[1] = SYSTEM_MENACER;
    input.x_offset = 60;
    input.y_offset = 30;
  }
  else if ((strstr(rominfo.international,"LETHAL ENFORCERS") != NULL) ||
           (strstr(rominfo.international,"SNATCHER") != NULL))
  {
    /* save current setting */
    if (old_system[0] == -1)
    {
      old_system[0] = input.system[0];
    }
    if (old_system[1] == -1)
    {
      old_system[1] = input.system[1];
    }

    /* force JUSTIFIER configuration */
    input.system[0] = SYSTEM_GAMEPAD;
    input.system[1] = SYSTEM_JUSTIFIER;
    input.x_offset = (strstr(rominfo.international,"GUN FIGHTERS") != NULL) ? 24 : 0;
    input.y_offset = 0;
  }

  return(1);
}