summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blastem.c39
-rw-r--r--blastem.h1
-rw-r--r--rom.db13
-rw-r--r--romdb.c26
-rw-r--r--romdb.h2
5 files changed, 64 insertions, 17 deletions
diff --git a/blastem.c b/blastem.c
index 0ffa8ec..ba1a48b 100644
--- a/blastem.c
+++ b/blastem.c
@@ -130,16 +130,10 @@ int load_rom(char * filename)
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 @@ void free_genesis(genesis_context *gen)
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 @@ int main(int argc, char ** argv)
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 @@ int main(int argc, char ** argv)
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 @@ int main(int argc, char ** argv)
(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 @@ int main(int argc, char ** argv)
}
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 @@ int main(int argc, char ** argv)
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);
diff --git a/blastem.h b/blastem.h
index eb1cc74..b096eb5 100644
--- a/blastem.h
+++ b/blastem.h
@@ -27,6 +27,7 @@ struct genesis_context {
psg_context *psg;
genesis_context *next_context;
uint16_t *cart;
+ uint16_t *lock_on;
uint16_t *work_ram;
uint8_t *zram;
void *extra;
diff --git a/rom.db b/rom.db
index 9b5bd57..08e8464 100644
--- a/rom.db
+++ b/rom.db
@@ -378,6 +378,19 @@ T-12046 {
}
}
}
+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
diff --git a/romdb.c b/romdb.c
index 4018db1..149814c 100644
--- a/romdb.c
+++ b/romdb.c
@@ -580,8 +580,10 @@ rom_info configure_rom_heuristics(uint8_t *rom, uint32_t rom_size, memmap_chunk
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 @@ void map_iter_fun(char *key, tern_val val, void *data)
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 @@ void map_iter_fun(char *key, tern_val val, void *data)
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 @@ rom_info configure_rom(tern_node *rom_db, void *vrom, uint32_t rom_size, memmap_
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 {
diff --git a/romdb.h b/romdb.h
index 724335e..846f44a 100644
--- a/romdb.h
+++ b/romdb.h
@@ -54,7 +54,7 @@ typedef struct {
} 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);