changeset 1016:5fb64487b6e1

Very basic support for S&K lock-on. Needs more work for full functionality.
author Michael Pavone <pavone@retrodev.com>
date Mon, 02 May 2016 21:06:12 -0700
parents 6c54d5a5c7c0
children 216fa63749b3
files blastem.c blastem.h rom.db romdb.c romdb.h
diffstat 5 files changed, 64 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/blastem.c	Mon May 02 18:29:29 2016 -0700
+++ b/blastem.c	Mon May 02 21:06:12 2016 -0700
@@ -130,16 +130,10 @@
 
 uint16_t read_dma_value(uint32_t address)
 {
-	//addresses here are word addresses (i.e. bit 0 corresponds to A1), so no need to do div by 2
-	if (address < 0x200000) {
-		return cart[address];
-	} else if(address >= 0x700000) {
-		return ram[address & 0x7FFF];
-	} else {
-		uint16_t *ptr = get_native_pointer(address*2, (void **)genesis->m68k->mem_pointers, &genesis->m68k->options->gen);
-		if (ptr) {
-			return *ptr;
-		}
+	//addresses here are word addresses (i.e. bit 0 corresponds to A1), so no need to do multiply by 2
+	uint16_t *ptr = get_native_pointer(address*2, (void **)genesis->m68k->mem_pointers, &genesis->m68k->options->gen);
+	if (ptr) {
+		return *ptr;
 	}
 	//TODO: Figure out what happens when you try to DMA from weird adresses like IO or banked Z80 area
 	return 0;
@@ -971,6 +965,7 @@
 	psg_free(gen->psg);
 	free(gen->save_storage);
 	free(gen->save_dir);
+	free(gen->lock_on);
 }
 
 void start_genesis(genesis_context *gen, char *statefile, uint8_t *debugger)
@@ -1070,7 +1065,8 @@
 	char * romfname = NULL;
 	FILE *address_log = NULL;
 	char * statefile = NULL;
-	int rom_size;
+	int rom_size, lock_on_size;
+	uint16_t *lock_on = NULL;
 	uint8_t * debuggerfun = NULL;
 	uint8_t fullscreen = FULLSCREEN_DEFAULT, use_gl = 1;
 	uint8_t debug_target = 0;
@@ -1135,6 +1131,22 @@
 			case 'y':
 				ym_log = 1;
 				break;
+			case 'o': {
+				i++;
+				if (i >= argc) {
+					fatal_error("-o must be followed by a lock on cartridge filename\n");
+				}
+				uint16_t *tmp = cart;
+				lock_on_size = load_rom(argv[i]);
+				if (lock_on_size) {
+					byteswap_rom(lock_on_size);
+					lock_on = cart;
+				} else {
+					fatal_error("Failed to load lock on cartridge %s\n", argv[i]);
+				}
+				cart = tmp;
+				break;
+			}
 			case 'h':
 				info_message(
 					"Usage: blastem [OPTIONS] ROMFILE [WIDTH] [HEIGHT]\n"
@@ -1212,7 +1224,7 @@
 		           (read_8_fun)io_read,         (write_8_fun)io_write}
 	};
 	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]));
+	rom_info info = configure_rom(rom_db, cart, rom_size, lock_on, lock_on_size, base_map, sizeof(base_map)/sizeof(base_map[0]));
 	byteswap_rom(rom_size);
 	set_region(&info, force_version);
 	update_title(info.name);
@@ -1235,6 +1247,7 @@
 	}
 
 	genesis = alloc_init_genesis(&info, fps, (ym_log && !menu) ? YM_OPT_WAVE_LOG : 0);
+	genesis->lock_on = lock_on;
 	setup_saves(romfname, &info, genesis);
 	if (menu) {
 		menu_context = genesis;
@@ -1266,7 +1279,7 @@
 			if (!(rom_size = load_rom(menu_context->next_rom))) {
 				fatal_error("Failed to open %s for reading\n", menu_context->next_rom);
 			}
-			info = configure_rom(rom_db, cart, rom_size, base_map, sizeof(base_map)/sizeof(base_map[0]));
+			info = configure_rom(rom_db, cart, rom_size, NULL, 0, base_map, sizeof(base_map)/sizeof(base_map[0]));
 			byteswap_rom(rom_size);
 			set_region(&info, force_version);
 			update_title(info.name);
--- a/blastem.h	Mon May 02 18:29:29 2016 -0700
+++ b/blastem.h	Mon May 02 21:06:12 2016 -0700
@@ -27,6 +27,7 @@
 	psg_context     *psg;
 	genesis_context *next_context;
 	uint16_t        *cart;
+	uint16_t        *lock_on;
 	uint16_t        *work_ram;
 	uint8_t         *zram;
 	void            *extra;
--- a/rom.db	Mon May 02 18:29:29 2016 -0700
+++ b/rom.db	Mon May 02 21:06:12 2016 -0700
@@ -378,6 +378,19 @@
 		}
 	}
 }
+MK-1563 {
+	name Sonic & Knuckles
+	map {
+		0 {
+			device ROM
+			last 1FFFFF
+		}
+		200000 {
+			device LOCK-ON
+			last 3FFFFF
+		}
+	}
+}
 T-48036 {
 	name Ms. Pac-Man
 	#Ms. Pac-Man doesn't like 6-button controllers
--- a/romdb.c	Mon May 02 18:29:29 2016 -0700
+++ b/romdb.c	Mon May 02 21:06:12 2016 -0700
@@ -580,8 +580,10 @@
 typedef struct {
 	rom_info     *info;
 	uint8_t      *rom;
+	uint8_t      *lock_on;
 	tern_node    *root;
 	uint32_t     rom_size;
+	uint32_t     lock_on_size;
 	int          index;
 	int          num_els;
 	uint16_t     ptr_index;
@@ -714,6 +716,14 @@
 		map->buffer = state->rom + offset;
 		map->flags = MMAP_READ;
 		map->mask = calc_mask(state->rom_size - offset, start, end);
+	} else if (!strcmp(dtype, "LOCK-ON")) {
+		if (!state->lock_on) {
+			//skip this entry if there is no lock on cartridge attached
+			return;
+		}
+		map->buffer = state->lock_on + offset;
+		map->flags = MMAP_READ;
+		map->mask = calc_mask(state->lock_on_size - offset, start, end);
 	} else if (!strcmp(dtype, "EEPROM")) {
 		process_eeprom_def(key, state);
 		add_eeprom_map(node, start, end, state);
@@ -797,12 +807,12 @@
 		map->write_16 = menu_write_w;
 		map->read_16 = menu_read_w;
 	} else {
-		fatal_error("Invalid device type for ROM DB map entry %d with address %s\n", state->index, key);
+		fatal_error("Invalid device type %s for ROM DB map entry %d with address %s\n", dtype, state->index, key);
 	}
 	state->index++;
 }
 
-rom_info configure_rom(tern_node *rom_db, void *vrom, uint32_t rom_size, memmap_chunk const *base_map, uint32_t base_chunks)
+rom_info configure_rom(tern_node *rom_db, void *vrom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, memmap_chunk const *base_map, uint32_t base_chunks)
 {
 	uint8_t product_id[GAME_ID_LEN+1];
 	uint8_t *rom = vrom;
@@ -855,7 +865,17 @@
 			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, 0};
+			map_iter_state state = {
+				.info = &info, 
+				.rom = rom, 
+				.lock_on = lock_on,
+				.root = entry, 
+				.rom_size = rom_size, 
+				.lock_on_size = lock_on_size,
+				.index = 0, 
+				.num_els = info.map_chunks - base_chunks,
+				.ptr_index = 0
+			};
 			tern_foreach(map, map_iter_fun, &state);
 			memcpy(info.map + state.index, base_map, sizeof(memmap_chunk) * base_chunks);
 		} else {
--- a/romdb.h	Mon May 02 18:29:29 2016 -0700
+++ b/romdb.h	Mon May 02 21:06:12 2016 -0700
@@ -54,7 +54,7 @@
 } rom_info;
 
 tern_node *load_rom_db();
-rom_info configure_rom(tern_node *rom_db, void *vrom, uint32_t rom_size, memmap_chunk const *base_map, uint32_t base_chunks);
+rom_info configure_rom(tern_node *rom_db, void *vrom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, memmap_chunk const *base_map, uint32_t base_chunks);
 rom_info configure_rom_heuristics(uint8_t *rom, uint32_t rom_size, memmap_chunk const *base_map, uint32_t base_chunks);
 uint8_t translate_region_char(uint8_t c);
 void eeprom_init(eeprom_state *state, uint8_t *buffer, uint32_t size);