changeset 764:bb60259e8edf

Initial work on ROM database
author Michael Pavone <pavone@retrodev.com>
date Thu, 02 Jul 2015 19:19:06 -0700
parents 206c449eaa81
children dc54387ee1cd
files Makefile blastem.c config.h rom.db romdb.c romdb.h
diffstat 6 files changed, 293 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Sun Jun 28 18:44:11 2015 -0700
+++ b/Makefile	Thu Jul 02 19:19:06 2015 -0700
@@ -99,7 +99,7 @@
 AUDIOOBJS=ym2612.o psg.o wave.o
 CONFIGOBJS=config.o tern.o util.o
 
-MAINOBJS=blastem.o debug.o gdb_remote.o vdp.o render_sdl.o io.o $(CONFIGOBJS) gst.o $(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS)
+MAINOBJS=blastem.o debug.o gdb_remote.o vdp.o render_sdl.o io.o romdb.o $(CONFIGOBJS) gst.o $(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS)
 
 ifeq ($(CPU),x86_64)
 CFLAGS+=-DX86_64 -m64
--- a/blastem.c	Sun Jun 28 18:44:11 2015 -0700
+++ b/blastem.c	Thu Jul 02 19:19:06 2015 -0700
@@ -13,6 +13,7 @@
 #include "gdb_remote.h"
 #include "gst.h"
 #include "util.h"
+#include "romdb.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -64,13 +65,21 @@
 	while (filesize > 0) {
 		fread(block, 1, SMD_BLOCK_SIZE, f);
 		for (uint8_t *low = block, *high = (block+SMD_BLOCK_SIZE/2), *end = block+SMD_BLOCK_SIZE; high < end; high++, low++) {
-			*(dst++) = *high << 8 | *low;
+			*(dst++) = *low << 8 | *high;
 		}
 		filesize -= SMD_BLOCK_SIZE;
 	}
 	return 1;
 }
 
+void byteswap_rom()
+{
+	for(unsigned short * cur = cart; cur - cart < CARTRIDGE_WORDS; ++cur)
+	{
+		*cur = (*cur >> 8) | (*cur << 8);
+	}
+}
+
 int load_rom(char * filename)
 {
 	uint8_t header[10];
@@ -103,11 +112,6 @@
 	}
 	fread(cart, 2, filesize/2, f);
 	fclose(f);
-	for(unsigned short * cur = cart; cur - cart < (filesize/2); ++cur)
-	{
-		*cur = (*cur >> 8) | (*cur << 8);
-	}
-	//TODO: Mirror ROM
 	return 1;
 }
 
@@ -1065,37 +1069,18 @@
 	}
 }
 
-char title[64];
+char *title;
 
 #define TITLE_START 0x150
 #define TITLE_END (TITLE_START+48)
 
-void update_title()
+void update_title(char *rom_name)
 {
-	uint16_t *last = cart + TITLE_END/2 - 1;
-	while(last > cart + TITLE_START/2 && *last == 0x2020)
-	{
-		last--;
+	if (title) {
+		free(title);
+		title = NULL;
 	}
-	uint16_t *start = cart + TITLE_START/2;
-	char *cur = title;
-	char last_char = ' ';
-	for (; start != last; start++)
-	{
-		if ((last_char != ' ' || (*start >> 8) != ' ') && (*start >> 8) < 0x80) {
-			*(cur++) = *start >> 8;
-			last_char = *start >> 8;
-		}
-		if (last_char != ' ' || (*start & 0xFF) != ' ' && (*start & 0xFF) < 0x80) {
-			*(cur++) = *start;
-			last_char = *start & 0xFF;
-		}
-	}
-	*(cur++) = *start >> 8;
-	if ((*start & 0xFF) != ' ') {
-		*(cur++) = *start;
-	}
-	strcpy(cur, " - BlastEm");
+	title = alloc_concat(rom_name, " - BlastEm");
 }
 
 #define REGION_START 0x1F0
@@ -1271,12 +1256,15 @@
 		fputs("You must specify a ROM filename!\n", stderr);
 		return 1;
 	}
+	tern_node *rom_db = load_rom_db();
+	rom_info info = configure_rom(rom_db, cart);
+	byteswap_rom();
 	if (force_version) {
 		version_reg = force_version;
 	} else {
 		detect_region();
 	}
-	update_title();
+	update_title(info.name);
 	int def_width = 0;
 	char *config_width = tern_find_ptr(config, "videowidth");
 	if (config_width) {
--- a/config.h	Sun Jun 28 18:44:11 2015 -0700
+++ b/config.h	Thu Jul 02 19:19:06 2015 -0700
@@ -7,6 +7,7 @@
 #define CONFIG_H_
 #include "tern.h"
 
+tern_node * parse_config_file(char * config_path);
 tern_node * load_config();
 
 #endif //CONFIG_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rom.db	Thu Jul 02 19:19:06 2015 -0700
@@ -0,0 +1,168 @@
+T-081326 {
+	name NBA Jam
+	eeprom {
+		type i2c
+		size 256
+	}
+	map {
+		0 {
+			device ROM
+			last 1FFFFF
+		}
+		200000 {
+			device eeprom
+			last 3FFFFF
+			bits_read {
+				1 sda
+			}
+			bits_write {
+				0 sda
+				1 scl
+			}
+		}
+	}
+}
+T-81033 {
+	name NBA Jam
+	eeprom {
+		type i2c
+		size 256
+	}
+	map {
+		0 {
+			device ROM
+			last 1FFFFF
+		}
+		200000 {
+			device eeprom
+			last 3FFFFF
+			bits_read {
+				1 sda
+			}
+			bits_write {
+				0 sda
+				1 scl
+			}
+		}
+	}
+}
+T-081276 {
+	name NFL Quarterback Club
+	eeprom {
+		type i2c
+		size 256
+	}
+	map {
+		0 {
+			device ROM
+			last 1FFFFF
+		}
+		200000 {
+			device eeprom
+			last 3FFFFF
+			bits_read {
+				0 sda
+			}
+			bits_write {
+				0 sda
+				8 scl
+			}
+		}
+	}
+}
+T-81406 {
+	name NBA Jam TE
+	eeprom {
+		type i2c
+		size 512
+	}
+	map {
+		0 {
+			device ROM
+			last 1FFFFF
+		}
+		200000 {
+			device eeprom
+			last 3FFFFF
+			bits_read {
+				0 sda
+			}
+			bits_write {
+				0 sda
+				8 scl
+			}
+		}
+	}
+}
+T-081586 {
+	name NFL Quarterback Club '96
+	eeprom {
+		type i2c
+		size 2048
+	}
+	map {
+		0 {
+			device ROM
+			last 1FFFFF
+		}
+		200000 {
+			device eeprom
+			last 3FFFFF
+			bits_read {
+				0 sda
+			}
+			bits_write {
+				0 sda
+				8 scl
+			}
+		}
+	}
+}
+T-81576 {
+	name College Slam
+	eeprom {
+		type i2c
+		size 8192
+	}
+	map {
+		0 {
+			device ROM
+			last 1FFFFF
+		}
+		200000 {
+			device eeprom
+			last 3FFFFF
+			bits_read {
+				0 sda
+			}
+			bits_write {
+				0 sda
+				8 scl
+			}
+		}
+	}
+}
+T-81476 {
+	name Frank Thomas Big Hurt Baseball
+	eeprom {
+		type i2c
+		size 8192
+	}
+	map {
+		0 {
+			device ROM
+			last 1FFFFF
+		}
+		200000 {
+			device eeprom
+			last 3FFFFF
+			bits_read {
+				0 sda
+			}
+			bits_write {
+				0 sda
+				8 scl
+			}
+		}
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/romdb.c	Thu Jul 02 19:19:06 2015 -0700
@@ -0,0 +1,83 @@
+#include <stdlib.h>
+#include <string.h>
+#include "config.h"
+#include "romdb.h"
+#include "util.h"
+
+#define GAME_ID_OFF 0x183
+#define GAME_ID_LEN 8
+#define TITLE_START 0x150
+#define TITLE_END (TITLE_START+48)
+
+tern_node *load_rom_db()
+{
+	char *exe_dir = get_exe_dir();
+	if (!exe_dir) {
+		fputs("Failed to find executable path\n", stderr);
+		exit(1);
+	}
+	char *path = alloc_concat(exe_dir, "/rom.db");
+	tern_node *db = parse_config_file(path);
+	free(path);
+	if (!db) {
+		fputs("Failed to load ROM DB\n", stderr);
+	}
+	return db;
+}
+
+char *get_header_name(uint8_t *rom)
+{
+	uint8_t *last = rom + TITLE_END - 1;
+	uint8_t *src = rom + TITLE_START;
+	
+	while (last > src && (*last <=  0x20 || *last >= 0x80))
+	{
+		last--;
+	}
+	if (last == src) {
+		//TODO: Use other name field
+		return strdup("UNKNOWN");
+	} else {
+		last++;
+		char *ret = malloc(last - (rom + TITLE_START) + 1);
+		uint8_t *dst;
+		for (dst = ret; src < last; src++)
+		{
+			if (*src >= 0x20 && *src < 0x80) {
+				*(dst++) = *src;
+			}
+		}
+		*dst = 0;
+		return ret;
+	}
+}
+
+rom_info configure_rom_heuristics(uint8_t *rom)
+{
+	rom_info info;
+	info.name = get_header_name(rom);
+	
+}
+
+rom_info configure_rom(tern_node *rom_db, void *vrom)
+{
+	uint8_t product_id[GAME_ID_LEN+1];
+	uint8_t *rom = vrom;
+	product_id[GAME_ID_LEN] = 0;
+	for (int i = 0; i < GAME_ID_LEN; i++)
+	{
+		if (rom[GAME_ID_OFF + i] <= ' ') {
+			product_id[i] = 0;
+			break;
+		}
+		product_id[i] = rom[GAME_ID_OFF + i];
+		
+	}
+	tern_node * entry = tern_find_prefix(rom_db, product_id);
+	if (!entry) {
+		return configure_rom_heuristics(rom);
+	}
+	rom_info info;
+	info.name = strdup(tern_find_ptr_default(entry, "name", "UNKNOWN"));
+	return info;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/romdb.h	Thu Jul 02 19:19:06 2015 -0700
@@ -0,0 +1,20 @@
+#ifndef ROMDB_H_
+#define ROMDB_H_
+
+#define REGION_J 1
+#define REGION_U 2
+#define REGION_E 4
+
+#include "tern.h"
+#include "backend.h"
+
+typedef struct {
+	char         *name;
+	memmap_chunk *map;
+	uint8_t      regions;
+} rom_info;
+
+tern_node *load_rom_db();
+rom_info configure_rom(tern_node *rom_db, void *vrom);
+
+#endif //ROMDB_H_