Mercurial > repos > blastem
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 { |