\r
static unsigned char id_header[0x100];\r
\r
-/* checks if fname points to valid MegaCD image\r
- * if so, checks for suitable BIOS */\r
+/* checks if fname points to valid MegaCD image */\r
static int emu_cd_check(int *pregion, const char *fname_in)\r
{\r
const char *fname = fname_in;\r
return type;\r
}\r
\r
+static int detect_media(const char *fname)\r
+{\r
+ static const short sms_offsets[] = { 0x7ff0, 0x3ff0, 0x1ff0 };\r
+ pm_file *pmf;\r
+ char buff[32];\r
+ char ext[5];\r
+ int i;\r
+\r
+ get_ext(fname, ext);\r
+\r
+ // detect wrong extensions\r
+ if (!strcmp(ext, ".srm") || !strcmp(ext, "s.gz") || !strcmp(ext, ".mds")) // s.gz ~ .mds.gz\r
+ return PM_BAD;\r
+\r
+ /* don't believe in extensions, except .cue */\r
+ if (strcasecmp(ext, ".cue") == 0)\r
+ return PM_CD;\r
+\r
+ pmf = pm_open(fname);\r
+ if (pmf == NULL)\r
+ return PM_BAD;\r
+\r
+ if (pm_read(buff, 32, pmf) != 32) {\r
+ pm_close(pmf);\r
+ return PM_BAD;\r
+ }\r
+\r
+ if (strncasecmp("SEGADISCSYSTEM", buff + 0x00, 14) == 0 ||\r
+ strncasecmp("SEGADISCSYSTEM", buff + 0x10, 14) == 0) {\r
+ pm_close(pmf);\r
+ return PM_CD;\r
+ }\r
+\r
+ for (i = 0; i < array_size(sms_offsets); i++) {\r
+ if (pm_seek(pmf, sms_offsets[i], SEEK_SET) != sms_offsets[i])\r
+ goto not_mark3; /* actually it could be but can't be detected */\r
+\r
+ if (pm_read(buff, 16, pmf) != 16)\r
+ goto not_mark3;\r
+\r
+ if (strncasecmp("TMR SEGA", buff, 8) == 0) {\r
+ pm_close(pmf);\r
+ return PM_MARK3;\r
+ }\r
+ }\r
+\r
+not_mark3:\r
+ pm_close(pmf);\r
+ /* the main emu function is to emulate MD, so assume MD */\r
+ return PM_MD_CART;\r
+}\r
+\r
static int extract_text(char *dest, const unsigned char *src, int len, int swab)\r
{\r
char *p = dest;\r
}\r
\r
// note: this function might mangle rom_fname\r
+// XXX: portions of this code should move to pico/\r
int emu_reload_rom(char *rom_fname)\r
{\r
unsigned int rom_size = 0;\r
unsigned char *rom_data = NULL;\r
char ext[5];\r
pm_file *rom = NULL;\r
- int ret, cd_state, cd_region, cfg_loaded = 0;\r
+ int cd_state = CIT_NOT_CD;\r
+ int ret, media_type, cd_region;\r
+ int cfg_loaded = 0, bad_rom = 0;\r
\r
lprintf("emu_ReloadRom(%s)\n", rom_fname);\r
\r
get_ext(rom_fname, ext);\r
\r
- // detect wrong extensions\r
- if (!strcmp(ext, ".srm") || !strcmp(ext, "s.gz") || !strcmp(ext, ".mds")) { // s.gz ~ .mds.gz\r
- me_update_msg("Not a ROM/CD selected.");\r
- return 0;\r
- }\r
-\r
- PicoPatchUnload();\r
-\r
// check for movie file\r
if (movie_data) {\r
free(movie_data);\r
get_ext(rom_fname, ext);\r
}\r
\r
+ media_type = detect_media(rom_fname);\r
+ if (media_type == PM_BAD) {\r
+ me_update_msg("Not a ROM/CD img selected.");\r
+ return 0;\r
+ }\r
+\r
shutdown_MCD();\r
+ PicoPatchUnload();\r
\r
- // check for MegaCD image\r
- cd_state = emu_cd_check(&cd_region, rom_fname);\r
- if (cd_state >= 0 && cd_state != CIT_NOT_CD)\r
+ if (media_type == PM_CD)\r
{\r
- PicoAHW |= PAHW_MCD;\r
- // valid CD image, check for BIOS..\r
+ // check for MegaCD image\r
+ cd_state = emu_cd_check(&cd_region, rom_fname);\r
+ if (cd_state >= 0 && cd_state != CIT_NOT_CD)\r
+ {\r
+ // valid CD image, check for BIOS..\r
\r
- // we need to have config loaded at this point\r
- ret = emu_read_config(1, 0);\r
- if (!ret) emu_read_config(0, 0);\r
- cfg_loaded = 1;\r
+ // we need to have config loaded at this point\r
+ ret = emu_read_config(1, 0);\r
+ if (!ret) emu_read_config(0, 0);\r
+ cfg_loaded = 1;\r
+\r
+ if (PicoRegionOverride) {\r
+ cd_region = PicoRegionOverride;\r
+ lprintf("override region to %s\n", cd_region != 4 ?\r
+ (cd_region == 8 ? "EU" : "JAP") : "USA");\r
+ }\r
+ if (!find_bios(cd_region, &used_rom_name))\r
+ return 0;\r
\r
- if (PicoRegionOverride) {\r
- cd_region = PicoRegionOverride;\r
- lprintf("overrided region to %s\n", cd_region != 4 ? (cd_region == 8 ? "EU" : "JAP") : "USA");\r
+ get_ext(used_rom_name, ext);\r
+ PicoAHW |= PAHW_MCD;\r
}\r
- if (!find_bios(cd_region, &used_rom_name)) {\r
- PicoAHW &= ~PAHW_MCD;\r
+ else {\r
+ me_update_msg("Invalid CD image");\r
return 0;\r
}\r
-\r
- get_ext(used_rom_name, ext);\r
}\r
- else\r
- {\r
- if (PicoAHW & PAHW_MCD) Stop_CD();\r
- PicoAHW &= ~PAHW_MCD;\r
+ else if (media_type == PM_MARK3) {\r
+ lprintf("detected SMS ROM\n");\r
+ PicoAHW = PAHW_SMS;\r
}\r
\r
rom = pm_open(used_rom_name);\r
- if (!rom) {\r
- me_update_msg("Failed to open ROM/CD image");\r
- goto fail;\r
- }\r
-\r
- if (cd_state < 0) {\r
- me_update_msg("Invalid CD image");\r
- goto fail;\r
+ if (rom == NULL) {\r
+ me_update_msg("Failed to open ROM");\r
+ return 0;\r
}\r
\r
menu_romload_prepare(used_rom_name); // also CD load\r
PicoCartUnload();\r
rom_loaded = 0;\r
\r
- if ( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) {\r
+ ret = PicoCartLoad(rom, &rom_data, &rom_size, (PicoAHW & PAHW_SMS) ? 1 : 0);\r
+ pm_close(rom);\r
+ if (ret != 0) {\r
if (ret == 2) me_update_msg("Out of memory");\r
else if (ret == 3) me_update_msg("Read failed");\r
else me_update_msg("PicoCartLoad() failed.");\r
- goto fail2;\r
+ goto fail;\r
}\r
- pm_close(rom);\r
- rom = NULL;\r
-\r
- // detect wrong files (Pico crashes on very small files), also see if ROM EP is good\r
- if (rom_size <= 0x200 || strncmp((char *)rom_data, "Pico", 4) == 0 ||\r
- ((*(unsigned char *)(rom_data+4)<<16)|(*(unsigned short *)(rom_data+6))) >= (int)rom_size) {\r
- if (rom_data) free(rom_data);\r
- me_update_msg("Not a ROM selected.");\r
- goto fail2;\r
+\r
+ // detect wrong files\r
+ if (strncmp((char *)rom_data, "Pico", 4) == 0)\r
+ bad_rom = 1;\r
+ else if (!(PicoAHW & PAHW_SMS)) {\r
+ unsigned short *d = (unsigned short *)(rom_data + 4);\r
+ if ((((d[0] << 16) | d[1]) & 0xffffff) >= (int)rom_size) {\r
+ lprintf("bad reset vector\n");\r
+ bad_rom = 1;\r
+ }\r
+ }\r
+\r
+ if (bad_rom) {\r
+ me_update_msg("Bad ROM detected.");\r
+ goto fail;\r
}\r
\r
// load config for this ROM (do this before insert to get correct region)\r
if (!ret) emu_read_config(0, 0);\r
}\r
\r
- lprintf("PicoCartInsert(%p, %d);\n", rom_data, rom_size);\r
if (PicoCartInsert(rom_data, rom_size)) {\r
me_update_msg("Failed to load ROM.");\r
- goto fail2;\r
+ goto fail;\r
}\r
\r
// insert CD if it was detected\r
if (cd_state != CIT_NOT_CD) {\r
ret = Insert_CD(rom_fname, cd_state);\r
if (ret != 0) {\r
+ PicoCartUnload();\r
+ rom_data = NULL; // freed by unload\r
me_update_msg("Insert_CD() failed, invalid CD image?");\r
- goto fail2;\r
+ goto fail;\r
}\r
}\r
\r
}\r
else\r
{\r
+ const char *sys_name, *tv_standard;\r
+ int fps;\r
+\r
+ if (PicoAHW & PAHW_SMS) {\r
+ sys_name = "Master System";\r
+ } else {\r
+ sys_name = "MegaDrive";\r
+ if ((Pico.m.hardware&0xc0) == 0x80)\r
+ sys_name = "Genesis";\r
+ }\r
+ tv_standard = Pico.m.pal ? "PAL" : "NTSC";\r
+ fps = Pico.m.pal ? 50 : 60;\r
+\r
+ emu_status_msg("%s %s / %dFPS", tv_standard, sys_name, fps);\r
+\r
PicoOpt &= ~POPT_DIS_VDP_FIFO;\r
- emu_status_msg(Pico.m.pal ? "PAL SYSTEM / 50 FPS" : "NTSC SYSTEM / 60 FPS");\r
}\r
\r
strncpy(rom_fname_loaded, rom_fname, sizeof(rom_fname_loaded)-1);\r
\r
return 1;\r
\r
-fail2:\r
- menu_romload_end();\r
fail:\r
- if (rom != NULL) pm_close(rom);\r
+ if (rom_data)\r
+ free(rom_data);\r
+ menu_romload_end();\r
return 0;\r
}\r
\r