changeset 776:cbf97d335444

Full support for Sega mapper when it comes to data. Code in remapped sections may not work reliably. SSF2 now works.
author Michael Pavone <pavone@retrodev.com>
date Mon, 20 Jul 2015 21:15:34 -0700
parents 22728a57d7f3
children 79b10b421d3c
files blastem.c blastem.h gst.c m68k_core.h rom.db romdb.c romdb.h
diffstat 7 files changed, 101 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/blastem.c	Sun Jul 19 22:30:40 2015 -0700
+++ b/blastem.c	Mon Jul 20 21:15:34 2015 -0700
@@ -34,7 +34,7 @@
 
 #define MAX_SOUND_CYCLES 100000
 
-uint16_t cart[CARTRIDGE_WORDS];
+uint16_t *cart;
 uint16_t ram[RAM_WORDS];
 uint8_t z80_ram[Z80_RAM_BYTES];
 
@@ -73,9 +73,9 @@
 	return filesize;
 }
 
-void byteswap_rom()
+void byteswap_rom(int filesize)
 {
-	for(unsigned short * cur = cart; cur - cart < CARTRIDGE_WORDS; ++cur)
+	for(unsigned short * cur = cart; cur - cart < filesize/2; ++cur)
 	{
 		*cur = (*cur >> 8) | (*cur << 8);
 	}
@@ -88,13 +88,12 @@
 	if (!f) {
 		return 0;
 	}
-	fread(header, 1, sizeof(header), f);
+	if (sizeof(header) != fread(header, 1, sizeof(header), f)) {
+		fprintf(stderr, "Error reading from %s\n", filename);
+		exit(1);
+	}
 	fseek(f, 0, SEEK_END);
 	long filesize = ftell(f);
-	if (filesize/2 > CARTRIDGE_WORDS) {
-		//carts bigger than 4MB not currently supported
-		filesize = CARTRIDGE_WORDS*2;
-	}
 	fseek(f, 0, SEEK_SET);
 	if (header[1] == SMD_MAGIC1 && header[8] == SMD_MAGIC2 && header[9] == SMD_MAGIC3) {
 		int i;
@@ -111,7 +110,11 @@
 			return load_smd_rom(filesize, f);
 		}
 	}
-	fread(cart, 2, filesize/2, f);
+	cart = malloc(filesize);
+	if (filesize != fread(cart, 1, filesize, f)) {
+		fprintf(stderr, "Error reading from %s\n", filename);
+		exit(1);
+	}
 	fclose(f);
 	return filesize;
 }
@@ -839,14 +842,12 @@
 
 	context->video_context = gen->vdp;
 	context->system = gen;
-	//cartridge ROM
-	context->mem_pointers[0] = cart;
-	context->target_cycle = context->sync_cycle = gen->frame_end > gen->max_cycles ? gen->frame_end : gen->max_cycles;
-	//work RAM
-	context->mem_pointers[1] = ram;
-	//save RAM/map
-	context->mem_pointers[2] = rom->map[1].buffer;
-	context->mem_pointers[3] = (uint16_t *)gen->save_storage;
+	for (int i = 0; i < rom->map_chunks; i++)
+	{
+		if (rom->map[i].flags & MMAP_PTR_IDX) {
+			context->mem_pointers[rom->map[i].ptr_index] = rom->map[i].buffer;
+		}
+	}
 	
 	if (statefile) {
 		uint32_t pc = load_gst(gen, statefile);
@@ -1026,7 +1027,7 @@
 	}
 	tern_node *rom_db = load_rom_db();
 	rom_info info = configure_rom(rom_db, cart, rom_size, base_map, sizeof(base_map)/sizeof(base_map[0]));
-	byteswap_rom();
+	byteswap_rom(rom_size);
 	set_region(&info, force_version);
 	update_title(info.name);
 	int def_width = 0;
--- a/blastem.h	Sun Jul 19 22:30:40 2015 -0700
+++ b/blastem.h	Mon Jul 20 21:15:34 2015 -0700
@@ -32,6 +32,7 @@
 	uint32_t       frame_end;
 	uint32_t       max_cycles;
 	uint8_t        bank_regs[8];
+	uint16_t       mapper_start_index;
 	uint8_t        save_type;
 	io_port        ports[3];
 	uint8_t        bus_busy;
@@ -44,11 +45,10 @@
 extern int save_state;
 extern tern_node * config;
 
-#define CARTRIDGE_WORDS 0x200000
 #define RAM_WORDS 32 * 1024
 #define Z80_RAM_BYTES 8 * 1024
 
-extern uint16_t cart[CARTRIDGE_WORDS];
+extern uint16_t *cart;
 extern uint16_t ram[RAM_WORDS];
 extern uint8_t z80_ram[Z80_RAM_BYTES];
 
--- a/gst.c	Sun Jul 19 22:30:40 2015 -0700
+++ b/gst.c	Mon Jul 20 21:15:34 2015 -0700
@@ -100,7 +100,7 @@
 			return 0;
 		}
 		for(curpos = buffer; curpos < (buffer + sizeof(buffer)); curpos += sizeof(uint16_t)) {
-			context->mem_pointers[1][i++] = read_be_16(curpos);
+			ram[i++] = read_be_16(curpos);
 		}
 	}
 	return pc;
@@ -141,7 +141,7 @@
 	fseek(gstfile, GST_68K_RAM, SEEK_SET);
 	for (int i = 0; i < (32*1024);) {
 		for(curpos = buffer; curpos < (buffer + sizeof(buffer)); curpos += sizeof(uint16_t)) {
-			write_be_16(curpos, context->mem_pointers[1][i++]);
+			write_be_16(curpos, ram[i++]);
 		}
 		if (fwrite(buffer, 1, sizeof(buffer), gstfile) != sizeof(buffer)) {
 			fputs("Failed to write 68K RAM to savestate\n", stderr);
--- a/m68k_core.h	Sun Jul 19 22:30:40 2015 -0700
+++ b/m68k_core.h	Mon Jul 20 21:15:34 2015 -0700
@@ -11,7 +11,7 @@
 //#include "68kinst.h"
 struct m68kinst;
 
-#define NUM_MEM_AREAS 4
+#define NUM_MEM_AREAS 8
 #define NATIVE_MAP_CHUNKS (64*1024)
 #define NATIVE_CHUNK_SIZE ((16 * 1024 * 1024 / NATIVE_MAP_CHUNKS)/2)
 #define MAX_NATIVE_SIZE 255
--- a/rom.db	Sun Jul 19 22:30:40 2015 -0700
+++ b/rom.db	Mon Jul 20 21:15:34 2015 -0700
@@ -173,4 +173,32 @@
 			}
 		}
 	}
+}
+MK-12056 {
+	name Super Street Fighter 2: The New Challengers
+	map {
+		0 {
+			device ROM
+			last 7FFFF
+		}
+		80000 {
+			device Sega mapper
+			last 3FFFFF
+			offset 80000
+		}
+	}
+}
+T-12056 {
+	name Super Street Fighter 2: The New Challengers
+	map {
+		0 {
+			device ROM
+			last 7FFFF
+		}
+		80000 {
+			device Sega mapper
+			last 3FFFFF
+			offset 80000
+		}
+	}
 }
\ No newline at end of file
--- a/romdb.c	Sun Jul 19 22:30:40 2015 -0700
+++ b/romdb.c	Mon Jul 20 21:15:34 2015 -0700
@@ -273,10 +273,21 @@
 	gen->bank_regs[address] = value;
 	if (!address) {
 		if (value & 1) {
-			context->mem_pointers[2] = NULL;
+			for (int i = 0; i < 8; i++)
+			{
+				context->mem_pointers[gen->mapper_start_index + i] = NULL;
+			}
 		} else {
-			context->mem_pointers[2] = cart + 0x200000/2;
+			//Used for games that only use the mapper for SRAM
+			context->mem_pointers[gen->mapper_start_index] = cart + 0x200000/2;
+			//For games that need more than 4MB
+			for (int i = 1; i < 8; i++)
+			{
+				context->mem_pointers[gen->mapper_start_index + i] = cart + 0x40000*gen->bank_regs[i];
+			}
 		}
+	} else {
+		context->mem_pointers[gen->mapper_start_index + address] = cart + 0x40000*value;
 	}
 	return context;
 }
@@ -284,17 +295,7 @@
 m68k_context * write_bank_reg_b(uint32_t address, m68k_context * context, uint8_t value)
 {
 	if (address & 1) {
-		genesis_context * gen = context->system;
-		address &= 0xE;
-		address >>= 1;
-		gen->bank_regs[address] = value;
-		if (!address) {
-			if (value & 1) {
-				context->mem_pointers[2] = NULL;
-			} else {
-				context->mem_pointers[2] = cart + 0x200000/2;
-			}
-		}
+		write_bank_reg_w(address, context, value);
 	}
 	return context;
 }
@@ -526,7 +527,7 @@
 			info->map[1].end = 0x400000;
 			info->map[1].mask = 0x1FFFFF;
 			info->map[1].flags = MMAP_READ | MMAP_PTR_IDX | MMAP_FUNC_NULL;
-			info->map[1].ptr_index = 2;
+			info->map[1].ptr_index = info->mapper_start_index = 0;
 			info->map[1].read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[2] == NULL
 			info->map[1].read_8 = (read_8_fun)read_sram_b;
 			info->map[1].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
@@ -571,6 +572,7 @@
 	uint32_t     rom_size;
 	int          index;
 	int          num_els;
+	uint16_t     ptr_index;
 } map_iter_state;
 
 void eeprom_read_fun(char *key, tern_val val, void *data)
@@ -727,31 +729,41 @@
 		}
 		map->mask = calc_mask(state->info->save_size, start, end);
 	} else if (!strcmp(dtype, "Sega mapper")) {
-		map->buffer = state->rom + offset;
-		//TODO: Calculate this
-		map->ptr_index = 2;
-		map->flags = MMAP_READ | MMAP_PTR_IDX | MMAP_FUNC_NULL;
-		map->mask = calc_mask(state->rom_size - offset, start, end);
+		state->info->mapper_start_index = state->ptr_index++;
+		state->info->map_chunks+=7;
+		state->info->map = realloc(state->info->map, sizeof(memmap_chunk) * state->info->map_chunks);
+		memset(state->info->map + state->info->map_chunks - 7, 0, sizeof(memmap_chunk) * 7);
+		map = state->info->map + state->index;
 		char *save_device = tern_find_path(node, "save\0device\0").ptrval;
-		if (save_device && !strcmp(save_device, "SRAM")) {
-			process_sram_def(key, state);
-			map->read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[2] == NULL
-			map->read_8 = (read_8_fun)read_sram_b;
-			map->write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
-			map->write_8 = (write_8_fun)write_sram_area_b;
-		} else if (save_device && !strcmp(save_device, "EEPROM")) {
+		if (save_device && !strcmp(save_device, "EEPROM")) {
 			process_eeprom_def(key, state);
 			add_eeprom_map(node, start & map->mask, end & map->mask, state);
-			map->write_16 = write_eeprom_i2c_w;
-			map->write_8 = write_eeprom_i2c_b;
-			map->read_16 = read_eeprom_i2c_w;
-			map->read_8 = read_eeprom_i2c_b;
 		}
-		state->info->map_chunks++;
-		state->info->map = realloc(state->info->map, sizeof(memmap_chunk) * state->info->map_chunks);
-		state->index++;
-		memset(state->info->map + state->info->map_chunks - 1, 0, sizeof(memmap_chunk));
-		map = state->info->map + state->index;
+		for (int i = 0; i < 7; i++, state->index++, map++)
+		{
+			map->start = start + i * 0x80000;
+			map->end = start + (i + 1) * 0x80000;
+			map->mask = 0x7FFFF;
+			map->buffer = state->rom + offset + i * 0x80000;
+			map->ptr_index = state->ptr_index++;
+			if (i < 3 || !save_device) {
+				map->flags = MMAP_READ | MMAP_PTR_IDX;
+			} else {
+				map->flags = MMAP_READ | MMAP_PTR_IDX | MMAP_FUNC_NULL;
+				if (!strcmp(save_device, "SRAM")) {
+					process_sram_def(key, state);
+					map->read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[2] == NULL
+					map->read_8 = (read_8_fun)read_sram_b;
+					map->write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
+					map->write_8 = (write_8_fun)write_sram_area_b;
+				} else if (!strcmp(save_device, "EEPROM")) {
+					map->write_16 = write_eeprom_i2c_w;
+					map->write_8 = write_eeprom_i2c_b;
+					map->read_16 = read_eeprom_i2c_w;
+					map->read_8 = read_eeprom_i2c_b;
+				}
+			}
+		}
 		map->start = 0xA13000;
 		map->end = 0xA13100;
 		map->mask = 0xFF;
@@ -817,7 +829,7 @@
 			info.eeprom_map = NULL;
 			info.num_eeprom = 0;
 			memset(info.map, 0, sizeof(memmap_chunk) * info.map_chunks);
-			map_iter_state state = {&info, rom, entry, rom_size, 0, info.map_chunks - base_chunks};
+			map_iter_state state = {&info, rom, entry, rom_size, 0, info.map_chunks - base_chunks, 0};
 			tern_foreach(map, map_iter_fun, &state);
 			memcpy(info.map + state.index, base_map, sizeof(memmap_chunk) * base_chunks);
 		} else {
--- a/romdb.h	Sun Jul 19 22:30:40 2015 -0700
+++ b/romdb.h	Mon Jul 20 21:15:34 2015 -0700
@@ -44,6 +44,7 @@
 	uint32_t      map_chunks;
 	uint32_t      save_size;
 	uint32_t      save_mask;
+	uint16_t      mapper_start_index;
 	uint8_t       save_type;
 	uint8_t       regions;
 } rom_info;