comparison romdb.c @ 1444:14a2834d010c

Save/restore mapper state in native save states
author Michael Pavone <pavone@retrodev.com>
date Sun, 27 Aug 2017 18:15:00 -0700
parents 49d3c572b3f2
children 1e3e0205640f a763523dadf4
comparison
equal deleted inserted replaced
1443:93c1b056ccdd 1444:14a2834d010c
54 free(info->map); 54 free(info->map);
55 free(info->port1_override); 55 free(info->port1_override);
56 free(info->port2_override); 56 free(info->port2_override);
57 free(info->ext_override); 57 free(info->ext_override);
58 free(info->mouse_mode); 58 free(info->mouse_mode);
59 }
60
61 void cart_serialize(system_header *sys, serialize_buffer *buf)
62 {
63 if (sys->type != SYSTEM_GENESIS) {
64 return;
65 }
66 genesis_context *gen = (genesis_context *)sys;
67 if (gen->mapper_type == MAPPER_NONE) {
68 return;
69 }
70 start_section(buf, SECTION_MAPPER);
71 save_int8(buf, gen->mapper_type);
72 switch(gen->mapper_type)
73 {
74 case MAPPER_SEGA:
75 sega_mapper_serialize(gen, buf);
76 break;
77 case MAPPER_REALTEC:
78 realtec_serialize(gen, buf);
79 break;
80 case MAPPER_XBAND:
81 xband_serialize(gen, buf);
82 break;
83 case MAPPER_MULTI_GAME:
84 multi_game_serialize(gen, buf);
85 break;
86 }
87 end_section(buf);
88 }
89
90 void cart_deserialize(deserialize_buffer *buf, void *vcontext)
91 {
92 genesis_context *gen = vcontext;
93 uint8_t mapper_type = load_int8(buf);
94 if (mapper_type != gen->mapper_type) {
95 warning("Mapper type mismatch, skipping load of mapper state");
96 return;
97 }
98 switch(gen->mapper_type)
99 {
100 case MAPPER_SEGA:
101 sega_mapper_deserialize(buf, gen);
102 break;
103 case MAPPER_REALTEC:
104 realtec_deserialize(buf, gen);
105 break;
106 case MAPPER_XBAND:
107 xband_deserialize(buf, gen);
108 break;
109 case MAPPER_MULTI_GAME:
110 multi_game_deserialize(buf, gen);
111 break;
112 }
59 } 113 }
60 114
61 char *get_header_name(uint8_t *rom) 115 char *get_header_name(uint8_t *rom)
62 { 116 {
63 //TODO: Should probably prefer the title field that corresponds to the user's region preference 117 //TODO: Should probably prefer the title field that corresponds to the user's region preference
195 } else if (rom_end > nearest_pow2(size)) { 249 } else if (rom_end > nearest_pow2(size)) {
196 rom_end = nearest_pow2(size); 250 rom_end = nearest_pow2(size);
197 } 251 }
198 if (size >= 0x80000 && !memcmp("SEGA SSF", rom + 0x100, 8)) { 252 if (size >= 0x80000 && !memcmp("SEGA SSF", rom + 0x100, 8)) {
199 info->mapper_start_index = 0; 253 info->mapper_start_index = 0;
254 info->mapper_type = MAPPER_SEGA;
200 info->map_chunks = base_chunks + 9; 255 info->map_chunks = base_chunks + 9;
201 info->map = malloc(sizeof(memmap_chunk) * info->map_chunks); 256 info->map = malloc(sizeof(memmap_chunk) * info->map_chunks);
202 memset(info->map, 0, sizeof(memmap_chunk)*9); 257 memset(info->map, 0, sizeof(memmap_chunk)*9);
203 memcpy(info->map+9, base_map, sizeof(memmap_chunk) * base_chunks); 258 memcpy(info->map+9, base_map, sizeof(memmap_chunk) * base_chunks);
204 259
263 info->map[1].flags |= MMAP_ONLY_EVEN; 318 info->map[1].flags |= MMAP_ONLY_EVEN;
264 } 319 }
265 info->map[1].buffer = info->save_buffer; 320 info->map[1].buffer = info->save_buffer;
266 } else { 321 } else {
267 //Assume the standard Sega mapper 322 //Assume the standard Sega mapper
323 info->mapper_type = MAPPER_SEGA;
268 info->map[0].end = 0x200000; 324 info->map[0].end = 0x200000;
269 info->map[0].mask = 0xFFFFFF; 325 info->map[0].mask = 0xFFFFFF;
270 info->map[0].flags = MMAP_READ; 326 info->map[0].flags = MMAP_READ;
271 info->map[0].buffer = rom; 327 info->map[0].buffer = rom;
272 328
306 } 362 }
307 363
308 rom_info configure_rom_heuristics(uint8_t *rom, uint32_t rom_size, memmap_chunk const *base_map, uint32_t base_chunks) 364 rom_info configure_rom_heuristics(uint8_t *rom, uint32_t rom_size, memmap_chunk const *base_map, uint32_t base_chunks)
309 { 365 {
310 rom_info info; 366 rom_info info;
367 info.mapper_type = MAPPER_NONE;
311 info.name = get_header_name(rom); 368 info.name = get_header_name(rom);
312 info.regions = get_header_regions(rom); 369 info.regions = get_header_regions(rom);
313 info.is_save_lock_on = 0; 370 info.is_save_lock_on = 0;
314 info.rom = rom; 371 info.rom = rom;
315 info.rom_size = rom_size; 372 info.rom_size = rom_size;
605 map->write_8 = nor_flash_write_b; 662 map->write_8 = nor_flash_write_b;
606 map->read_16 = nor_flash_read_w; 663 map->read_16 = nor_flash_read_w;
607 map->read_8 = nor_flash_read_b; 664 map->read_8 = nor_flash_read_b;
608 map->mask = 0xFFFFFF; 665 map->mask = 0xFFFFFF;
609 } else if (!strcmp(dtype, "Sega mapper")) { 666 } else if (!strcmp(dtype, "Sega mapper")) {
667 state->info->mapper_type = MAPPER_SEGA;
610 state->info->mapper_start_index = state->ptr_index++; 668 state->info->mapper_start_index = state->ptr_index++;
611 char *variant = tern_find_ptr_default(node, "variant", "full"); 669 char *variant = tern_find_ptr_default(node, "variant", "full");
612 char *save_device = tern_find_path(node, "save\0device\0", TVAL_PTR).ptrval; 670 char *save_device = tern_find_path(node, "save\0device\0", TVAL_PTR).ptrval;
613 if (save_device && !strcmp(save_device, "EEPROM")) { 671 if (save_device && !strcmp(save_device, "EEPROM")) {
614 process_eeprom_def(key, state); 672 process_eeprom_def(key, state);
692 map->buffer = value; 750 map->buffer = value;
693 map->mask = 0; 751 map->mask = 0;
694 map->flags = MMAP_READ; 752 map->flags = MMAP_READ;
695 *value = strtol(tern_find_ptr_default(node, "value", "0"), NULL, 16); 753 *value = strtol(tern_find_ptr_default(node, "value", "0"), NULL, 16);
696 } else if (!strcmp(dtype, "multi-game")) { 754 } else if (!strcmp(dtype, "multi-game")) {
755 state->info->mapper_type = MAPPER_MULTI_GAME;
697 state->info->mapper_start_index = state->ptr_index++; 756 state->info->mapper_start_index = state->ptr_index++;
698 //make a mirror copy of the ROM so we can efficiently support arbitrary start offsets 757 //make a mirror copy of the ROM so we can efficiently support arbitrary start offsets
699 state->rom = realloc(state->rom, state->rom_size * 2); 758 state->rom = realloc(state->rom, state->rom_size * 2);
700 memcpy(state->rom + state->rom_size, state->rom, state->rom_size); 759 memcpy(state->rom + state->rom_size, state->rom, state->rom_size);
701 state->rom_size *= 2; 760 state->rom_size *= 2;
754 return realtec_configure_rom(rom, rom_size, base_map, base_chunks); 813 return realtec_configure_rom(rom, rom_size, base_map, base_chunks);
755 } 814 }
756 return configure_rom_heuristics(rom, rom_size, base_map, base_chunks); 815 return configure_rom_heuristics(rom, rom_size, base_map, base_chunks);
757 } 816 }
758 rom_info info; 817 rom_info info;
818 info.mapper_type = MAPPER_NONE;
759 info.name = tern_find_ptr(entry, "name"); 819 info.name = tern_find_ptr(entry, "name");
760 if (info.name) { 820 if (info.name) {
761 printf("Found name: %s\n", info.name); 821 printf("Found name: %s\n", info.name);
762 info.name = strdup(info.name); 822 info.name = strdup(info.name);
763 } else { 823 } else {