Mercurial > repos > blastem
comparison romdb.c @ 1411:780fbe0b97be
WIP support for handling S3 save RAM when locked on
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 22 Jun 2017 09:49:41 -0700 |
parents | 4cd4aa6be5f6 |
children | 3d7f668dce3d |
comparison
equal
deleted
inserted
replaced
1410:4cd4aa6be5f6 | 1411:780fbe0b97be |
---|---|
614 fatal_error("Failed to load ROM DB\n"); | 614 fatal_error("Failed to load ROM DB\n"); |
615 } | 615 } |
616 return db; | 616 return db; |
617 } | 617 } |
618 | 618 |
619 void free_rom_info(rom_info *info) | |
620 { | |
621 free(info->name); | |
622 if (info->save_type != SAVE_NONE) { | |
623 free(info->save_buffer); | |
624 if (info->save_type == SAVE_I2C) { | |
625 free(info->eeprom_map); | |
626 } | |
627 } | |
628 free(info->map); | |
629 free(info->port1_override); | |
630 free(info->port2_override); | |
631 free(info->ext_override); | |
632 free(info->mouse_mode); | |
633 } | |
634 | |
619 char *get_header_name(uint8_t *rom) | 635 char *get_header_name(uint8_t *rom) |
620 { | 636 { |
621 //TODO: Should probably prefer the title field that corresponds to the user's region preference | 637 //TODO: Should probably prefer the title field that corresponds to the user's region preference |
622 uint8_t *last = rom + TITLE_END - 1; | 638 uint8_t *last = rom + TITLE_END - 1; |
623 uint8_t *src = rom + TITLE_START; | 639 uint8_t *src = rom + TITLE_START; |
868 typedef struct { | 884 typedef struct { |
869 rom_info *info; | 885 rom_info *info; |
870 uint8_t *rom; | 886 uint8_t *rom; |
871 uint8_t *lock_on; | 887 uint8_t *lock_on; |
872 tern_node *root; | 888 tern_node *root; |
889 tern_node *rom_db; | |
873 uint32_t rom_size; | 890 uint32_t rom_size; |
874 uint32_t lock_on_size; | 891 uint32_t lock_on_size; |
875 int index; | 892 int index; |
876 int num_els; | 893 int num_els; |
877 uint16_t ptr_index; | 894 uint16_t ptr_index; |
1049 if (!strcmp(dtype, "ROM")) { | 1066 if (!strcmp(dtype, "ROM")) { |
1050 map->buffer = state->rom + offset; | 1067 map->buffer = state->rom + offset; |
1051 map->flags = MMAP_READ; | 1068 map->flags = MMAP_READ; |
1052 map->mask = calc_mask(state->rom_size - offset, start, end); | 1069 map->mask = calc_mask(state->rom_size - offset, start, end); |
1053 } else if (!strcmp(dtype, "LOCK-ON")) { | 1070 } else if (!strcmp(dtype, "LOCK-ON")) { |
1054 map->flags = MMAP_READ; | 1071 rom_info lock_info; |
1055 if (state->lock_on) { | 1072 if (state->lock_on) { |
1056 if (state->lock_on_size > offset) { | 1073 lock_info = configure_rom(state->rom_db, state->lock_on, state->lock_on_size, NULL, 0, NULL, 0); |
1057 map->mask = calc_mask(state->lock_on_size - offset, start, end); | |
1058 } else { | |
1059 map->mask = calc_mask(state->lock_on_size, start, end); | |
1060 } | |
1061 map->buffer = state->lock_on + (offset & (nearest_pow2(state->lock_on_size) - 1)); | |
1062 } else if (state->rom_size > start) { | 1074 } else if (state->rom_size > start) { |
1063 //This is a bit of a hack to deal with pre-combined S3&K/S2&K ROMs and S&K ROM hacks | 1075 //This is a bit of a hack to deal with pre-combined S3&K/S2&K ROMs and S&K ROM hacks |
1064 map->buffer = state->rom + start; | 1076 lock_info = configure_rom(state->rom_db, state->rom + start, state->rom_size - start, NULL, 0, NULL, 0); |
1065 map->mask = calc_mask(state->rom_size - start, start, end); | |
1066 if (has_ram_header(map->buffer, state->rom_size - start)) { | |
1067 uint32_t sram_start = read_ram_header(state->info, map->buffer); | |
1068 | |
1069 state->info->map_chunks+=1; | |
1070 state->info->map = realloc(state->info->map, sizeof(memmap_chunk) * state->info->map_chunks); | |
1071 memset(state->info->map + state->info->map_chunks - 1, 0, sizeof(memmap_chunk) * 1); | |
1072 if (sram_start >= state->rom_size) { | |
1073 map = state->info->map + ++state->index; | |
1074 map->start = sram_start; | |
1075 map->mask = state->info->save_mask; | |
1076 map->end = sram_start + state->info->save_mask + 1; | |
1077 map->flags = MMAP_READ | MMAP_WRITE; | |
1078 if (state->info->save_type == RAM_FLAG_ODD) { | |
1079 map->flags |= MMAP_ONLY_ODD; | |
1080 } else if (state->info->save_type == RAM_FLAG_EVEN) { | |
1081 map->flags |= MMAP_ONLY_EVEN; | |
1082 } | |
1083 map->buffer = state->info->save_buffer; | |
1084 } else { | |
1085 map = state->info->map + state->index++; | |
1086 map->flags |= MMAP_CODE | MMAP_PTR_IDX | MMAP_FUNC_NULL; | |
1087 state->info->mapper_start_index = state->ptr_index++; | |
1088 map->ptr_index = state->info->mapper_start_index; | |
1089 map->read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[ptr_idx] == NULL | |
1090 map->read_8 = (read_8_fun)read_sram_b; | |
1091 map->write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area | |
1092 map->write_8 = (write_8_fun)write_sram_area_b; | |
1093 | |
1094 map = state->info->map + state->index; | |
1095 map->start = 0xA13000; | |
1096 map->end = 0xA13100; | |
1097 map->mask = 0xFF; | |
1098 map->write_16 = (write_16_fun)write_bank_reg_w; | |
1099 map->write_8 = (write_8_fun)write_bank_reg_b; | |
1100 } | |
1101 } | |
1102 } else { | 1077 } else { |
1103 //skip this entry if there is no lock on cartridge attached | 1078 //skip this entry if there is no lock on cartridge attached |
1104 return; | 1079 return; |
1105 } | 1080 } |
1081 uint32_t matching_chunks = 0; | |
1082 for (int i = 0; i < lock_info.map_chunks; i++) | |
1083 { | |
1084 if (lock_info.map[i].start < 0xC00000 && lock_info.map[i].end > 0x200000) { | |
1085 matching_chunks++; | |
1086 } | |
1087 } | |
1088 if (matching_chunks == 0) { | |
1089 //Nothing mapped in the relevant range for the lock-on cart, ignore this mapping | |
1090 return; | |
1091 } else if (matching_chunks > 1) { | |
1092 state->info->map_chunks += matching_chunks - 1; | |
1093 state->info->map = realloc(state->info->map, sizeof(memmap_chunk) * state->info->map_chunks); | |
1094 memset(state->info->map + state->info->map_chunks - (matching_chunks - 1), 0, sizeof(memmap_chunk) * (matching_chunks - 1)); | |
1095 map = state->info->map + state->index; | |
1096 } | |
1097 for (int i = 0; i < matching_chunks; i++) | |
1098 { | |
1099 if (lock_info.map[i].start >= 0xC00000 || lock_info.map[i].end <= 0x200000) { | |
1100 continue; | |
1101 } | |
1102 *map = lock_info.map[i]; | |
1103 if (map->start < 0x200000) { | |
1104 if (map->buffer) { | |
1105 map->buffer += (0x200000 - map->start) & ((map->flags & MMAP_AUX_BUFF) ? map->aux_mask : map->mask); | |
1106 } | |
1107 map->start = 0x200000; | |
1108 } | |
1109 map++; | |
1110 state->index++; | |
1111 } | |
1112 if (state->info->save_type == SAVE_NONE && lock_info.save_type != SAVE_NONE) { | |
1113 //main cart has no save device, but lock-on cart does | |
1114 if (state->lock_on) { | |
1115 state->info->is_save_lock_on = 1; | |
1116 } | |
1117 state->info->save_buffer = lock_info.save_buffer; | |
1118 state->info->save_size = lock_info.save_size; | |
1119 state->info->save_mask = lock_info.save_mask; | |
1120 state->info->save_page_size = lock_info.save_page_size; | |
1121 state->info->save_product_id = lock_info.save_product_id; | |
1122 state->info->save_type = lock_info.save_type; | |
1123 state->info->save_bus = lock_info.save_bus; | |
1124 lock_info.save_buffer = NULL; | |
1125 lock_info.save_type = SAVE_NONE; | |
1126 } | |
1127 free_rom_info(&lock_info); | |
1128 return; | |
1106 } else if (!strcmp(dtype, "EEPROM")) { | 1129 } else if (!strcmp(dtype, "EEPROM")) { |
1107 process_eeprom_def(key, state); | 1130 process_eeprom_def(key, state); |
1108 add_eeprom_map(node, start, end, state); | 1131 add_eeprom_map(node, start, end, state); |
1109 | 1132 |
1110 map->write_16 = write_eeprom_i2c_w; | 1133 map->write_16 = write_eeprom_i2c_w; |
1280 memset(info.map, 0, sizeof(memmap_chunk) * info.map_chunks); | 1303 memset(info.map, 0, sizeof(memmap_chunk) * info.map_chunks); |
1281 map_iter_state state = { | 1304 map_iter_state state = { |
1282 .info = &info, | 1305 .info = &info, |
1283 .rom = rom, | 1306 .rom = rom, |
1284 .lock_on = lock_on, | 1307 .lock_on = lock_on, |
1285 .root = entry, | 1308 .root = entry, |
1309 .rom_db = rom_db, | |
1286 .rom_size = rom_size, | 1310 .rom_size = rom_size, |
1287 .lock_on_size = lock_on_size, | 1311 .lock_on_size = lock_on_size, |
1288 .index = 0, | 1312 .index = 0, |
1289 .num_els = info.map_chunks - base_chunks, | 1313 .num_els = info.map_chunks - base_chunks, |
1290 .ptr_index = 0 | 1314 .ptr_index = 0 |