diff system.c @ 1140:4490c9c12272

Detect system type from filename if header based methods fail. Allow overriding system type from command line.
author Michael Pavone <pavone@retrodev.com>
date Mon, 02 Jan 2017 21:46:26 -0800
parents 928a65750345
children aee2177a1630
line wrap: on
line diff
--- a/system.c	Mon Jan 02 16:33:03 2017 -0800
+++ b/system.c	Mon Jan 02 21:46:26 2017 -0800
@@ -9,24 +9,38 @@
 	return filesize >= offset+len && !memcmp(str, buffer + offset, len);
 }
 
-system_type detect_system_type(uint8_t *rom, long filesize)
+system_type detect_system_type(system_media *media)
 {
-	if (safe_cmp("SEGA", 0x100, rom, filesize)) {
+	if (safe_cmp("SEGA", 0x100, media->buffer, media->size)) {
 		//TODO: Differentiate between vanilla Genesis and Sega CD/32X games
 		return SYSTEM_GENESIS;
 	}
-	if (safe_cmp("TMR SEGA", 0x1FF0, rom, filesize) 
-		|| safe_cmp("TMR SEGA", 0x3FF0, rom, filesize) 
-		|| safe_cmp("TMR SEGA", 0x7FF0, rom, filesize) 
+	if (safe_cmp("TMR SEGA", 0x1FF0, media->buffer, media->size)
+		|| safe_cmp("TMR SEGA", 0x3FF0, media->buffer, media->size)
+		|| safe_cmp("TMR SEGA", 0x7FF0, media->buffer, media->size)
 	) {
 		return SYSTEM_SMS;
 	}
 	//TODO: Detect Jaguar ROMs here
 	
+	//Header based detection failed, examine filename for clues
+	if (media->extension) {
+		if (!strcmp("md", media->extension) || !strcmp("gen", media->extension)) {
+			return SYSTEM_GENESIS;
+		}
+		if (!strcmp("sms", media->extension)) {
+			return SYSTEM_SMS;
+		}
+		if (!strcmp("j64", media->extension)) {
+			return SYSTEM_JAGUAR;
+		}
+	}
+	
 	//More certain checks failed, look for a valid 68K reset vector
-	if (filesize >= 8) {
+	if (media->size >= 8) {
+		char *rom = media->buffer;
 		uint32_t reset = rom[4] << 24 | rom[5] << 16 | rom[6] << 8 | rom[7];
-		if (!(reset & 1) && reset < filesize) {
+		if (!(reset & 1) && reset < media->size) {
 			//we have a valid looking reset vector, assume it's a Genesis ROM
 			return SYSTEM_GENESIS;
 		}
@@ -34,15 +48,21 @@
 	return SYSTEM_UNKNOWN;
 }
 
-system_header *alloc_config_system(system_type stype, void *rom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, uint32_t opts, uint8_t force_region, rom_info *info_out)
+system_header *alloc_config_system(system_type stype, system_media *media, uint32_t opts, uint8_t force_region, rom_info *info_out)
 {
+	void *lock_on = NULL;
+	uint32_t lock_on_size = 0;
+	if (media->chain) {
+		lock_on = media->chain->buffer;
+		lock_on_size = media->chain->size;
+	}
 	switch (stype)
 	{
 	case SYSTEM_GENESIS:
-		return &(alloc_config_genesis(rom, rom_size, lock_on, lock_on_size, opts, force_region, info_out))->header;
+		return &(alloc_config_genesis(media->buffer, media->size, lock_on, lock_on_size, opts, force_region, info_out))->header;
 #ifndef NO_Z80
 	case SYSTEM_SMS:
-		return &(alloc_configure_sms(rom, rom_size, lock_on, lock_on_size, opts, force_region, info_out))->header;
+		return &(alloc_configure_sms(media->buffer, media->size, lock_on, lock_on_size, opts, force_region, info_out))->header;
 #endif
 	default:
 		return NULL;