main system.c
 1#include <string.h>
 2#include "system.h"
 3#include "genesis.h"
 4#include "sms.h"
 5
 6uint8_t safe_cmp(char *str, long offset, uint8_t *buffer, long filesize)
 7{
 8	long len = strlen(str);
 9	return filesize >= offset+len && !memcmp(str, buffer + offset, len);
10}
11
12system_type detect_system_type(system_media *media)
13{
14	if (safe_cmp("SEGA", 0x100, media->buffer, media->size)) {
15		//TODO: Differentiate between vanilla Genesis and Sega CD/32X games
16		return SYSTEM_GENESIS;
17	}
18	if (safe_cmp("TMR SEGA", 0x1FF0, media->buffer, media->size)
19		|| safe_cmp("TMR SEGA", 0x3FF0, media->buffer, media->size)
20		|| safe_cmp("TMR SEGA", 0x7FF0, media->buffer, media->size)
21	) {
22		return SYSTEM_SMS;
23	}
24	//TODO: Detect Jaguar ROMs here
25	
26	//Header based detection failed, examine filename for clues
27	if (media->extension) {
28		if (!strcmp("md", media->extension) || !strcmp("gen", media->extension)) {
29			return SYSTEM_GENESIS;
30		}
31		if (!strcmp("sms", media->extension)) {
32			return SYSTEM_SMS;
33		}
34	}
35	
36	//More certain checks failed, look for a valid 68K reset vector
37	if (media->size >= 8) {
38		char *rom = media->buffer;
39		uint32_t reset = rom[4] << 24 | rom[5] << 16 | rom[6] << 8 | rom[7];
40		if (!(reset & 1) && reset < media->size) {
41			//we have a valid looking reset vector, assume it's a Genesis ROM
42			return SYSTEM_GENESIS;
43		}
44	}
45	return SYSTEM_UNKNOWN;
46}
47
48system_header *alloc_config_system(system_type stype, system_media *media, uint32_t opts, uint8_t force_region)
49{
50	void *lock_on = NULL;
51	uint32_t lock_on_size = 0;
52	if (media->chain) {
53		lock_on = media->chain->buffer;
54		lock_on_size = media->chain->size;
55	}
56	switch (stype)
57	{
58	case SYSTEM_GENESIS:
59		return &(alloc_config_genesis(media->buffer, media->size, lock_on, lock_on_size, opts, force_region))->header;
60	case SYSTEM_SMS:
61		return &(alloc_configure_sms(media, opts, force_region))->header;
62	default:
63		return NULL;
64	}
65}