main
romdb.c
1#include <stdlib.h>
2#include <string.h>
3#include "config.h"
4#include "romdb.h"
5#include "util.h"
6#include "hash.h"
7#include "genesis.h"
8#include "menu.h"
9#include "xband.h"
10#include "realtec.h"
11#include "nor.h"
12#include "sega_mapper.h"
13#include "multi_game.h"
14#include "megawifi.h"
15#include "jcart.h"
16#include "blastem.h"
17
18#define DOM_TITLE_START 0x120
19#define DOM_TITLE_END 0x150
20#define TITLE_START DOM_TITLE_END
21#define TITLE_END (TITLE_START+48)
22#define ROM_END 0x1A4
23#define RAM_ID 0x1B0
24#define RAM_FLAGS 0x1B2
25#define RAM_START 0x1B4
26#define RAM_END 0x1B8
27#define REGION_START 0x1F0
28
29char const *save_type_name(uint8_t save_type)
30{
31 if (save_type == SAVE_I2C) {
32 return "EEPROM";
33 } else if(save_type == SAVE_NOR) {
34 return "NOR Flash";
35 }
36 return "SRAM";
37}
38
39tern_node *load_rom_db()
40{
41 tern_node *db = parse_bundled_config("rom.db");
42 if (!db) {
43 fatal_error("Failed to load ROM DB\n");
44 }
45 return db;
46}
47
48void free_rom_info(rom_info *info)
49{
50 free(info->name);
51 if (info->save_type != SAVE_NONE) {
52 free(info->save_buffer);
53 if (info->save_type == SAVE_I2C) {
54 free(info->eeprom_map);
55 } else if (info->save_type == SAVE_NOR) {
56 free(info->nor);
57 }
58 }
59 free(info->map);
60 free(info->port1_override);
61 free(info->port2_override);
62 free(info->ext_override);
63 free(info->mouse_mode);
64}
65
66void cart_serialize(system_header *sys, serialize_buffer *buf)
67{
68 if (sys->type != SYSTEM_GENESIS) {
69 return;
70 }
71 genesis_context *gen = (genesis_context *)sys;
72 if (gen->mapper_type == MAPPER_NONE) {
73 return;
74 }
75 start_section(buf, SECTION_MAPPER);
76 save_int8(buf, gen->mapper_type);
77 switch(gen->mapper_type)
78 {
79 case MAPPER_SEGA:
80 sega_mapper_serialize(gen, buf);
81 break;
82 case MAPPER_REALTEC:
83 realtec_serialize(gen, buf);
84 break;
85 case MAPPER_XBAND:
86 xband_serialize(gen, buf);
87 break;
88 case MAPPER_MULTI_GAME:
89 multi_game_serialize(gen, buf);
90 break;
91 }
92 end_section(buf);
93}
94
95void cart_deserialize(deserialize_buffer *buf, void *vcontext)
96{
97 genesis_context *gen = vcontext;
98 uint8_t mapper_type = load_int8(buf);
99 if (mapper_type != gen->mapper_type) {
100 warning("Mapper type mismatch, skipping load of mapper state");
101 return;
102 }
103 switch(gen->mapper_type)
104 {
105 case MAPPER_SEGA:
106 sega_mapper_deserialize(buf, gen);
107 break;
108 case MAPPER_REALTEC:
109 realtec_deserialize(buf, gen);
110 break;
111 case MAPPER_XBAND:
112 xband_deserialize(buf, gen);
113 break;
114 case MAPPER_MULTI_GAME:
115 multi_game_deserialize(buf, gen);
116 break;
117 }
118}
119
120char *get_header_name(uint8_t *rom)
121{
122 //TODO: Should probably prefer the title field that corresponds to the user's region preference
123 uint8_t *last = rom + TITLE_END - 1;
124 uint8_t *src = rom + TITLE_START;
125
126 for (;;)
127 {
128 while (last > src && (*last <= 0x20 || *last >= 0x80))
129 {
130 last--;
131 }
132 if (last == src) {
133 if (src == rom + TITLE_START) {
134 src = rom + DOM_TITLE_START;
135 last = rom + DOM_TITLE_END - 1;
136 } else {
137 return strdup("UNKNOWN");
138 }
139 } else {
140 last++;
141 char *ret = malloc(last - src + 1);
142 uint8_t *dst;
143 uint8_t last_was_space = 1;
144 for (dst = ret; src < last; src++)
145 {
146 if (*src >= 0x20 && *src < 0x80) {
147 if (*src == ' ') {
148 if (last_was_space) {
149 continue;
150 }
151 last_was_space = 1;
152 } else {
153 last_was_space = 0;
154 }
155 *(dst++) = *src;
156 }
157 }
158 *dst = 0;
159 return ret;
160 }
161 }
162}
163
164char *region_chars = "JUEW";
165uint8_t region_bits[] = {REGION_J, REGION_U, REGION_E, REGION_J|REGION_U|REGION_E};
166
167uint8_t translate_region_char(uint8_t c)
168{
169 for (int i = 0; i < sizeof(region_bits); i++)
170 {
171 if (c == region_chars[i]) {
172 return region_bits[i];
173 }
174 }
175 uint8_t bin_region = 0;
176 if (c >= '0' && c <= '9') {
177 bin_region = c - '0';
178 } else if (c >= 'A' && c <= 'F') {
179 bin_region = c - 'A' + 0xA;
180 } else if (c >= 'a' && c <= 'f') {
181 bin_region = c - 'a' + 0xA;
182 }
183 uint8_t ret = 0;
184 if (bin_region & 8) {
185 ret |= REGION_E;
186 }
187 if (bin_region & 4) {
188 ret |= REGION_U;
189 }
190 if (bin_region & 1) {
191 ret |= REGION_J;
192 }
193 return ret;
194}
195
196uint8_t get_header_regions(uint8_t *rom)
197{
198 uint8_t regions = 0;
199 for (int i = 0; i < 3; i++)
200 {
201 regions |= translate_region_char(rom[REGION_START + i]);
202 }
203 return regions;
204}
205
206uint32_t get_u32be(uint8_t *data)
207{
208 return *data << 24 | data[1] << 16 | data[2] << 8 | data[3];
209}
210
211uint32_t calc_mask(uint32_t src_size, uint32_t start, uint32_t end)
212{
213 uint32_t map_size = end-start+1;
214 if (src_size < map_size) {
215 return nearest_pow2(src_size)-1;
216 } else if (!start) {
217 return 0xFFFFFF;
218 } else {
219 return nearest_pow2(map_size)-1;
220 }
221}
222
223uint8_t has_ram_header(uint8_t *rom, uint32_t rom_size)
224{
225 return rom_size >= (RAM_END + 4) && rom[RAM_ID] == 'R' && rom[RAM_ID + 1] == 'A';
226}
227
228uint32_t read_ram_header(rom_info *info, uint8_t *rom)
229{
230 uint32_t ram_start = get_u32be(rom + RAM_START);
231 uint32_t ram_end = get_u32be(rom + RAM_END);
232 uint32_t ram_flags = info->save_type = rom[RAM_FLAGS] & RAM_FLAG_MASK;
233 ram_start &= 0xFFFFFE;
234 ram_end |= 1;
235 if (ram_start >= 0x800000) {
236 info->save_buffer = NULL;
237 return ram_start;
238 }
239 info->save_mask = ram_end - ram_start;
240 uint32_t save_size = info->save_mask + 1;
241 if (ram_flags != RAM_FLAG_BOTH) {
242 save_size /= 2;
243 }
244 info->save_size = save_size;
245 info->save_buffer = malloc(save_size);
246 return ram_start;
247}
248
249void add_memmap_header(rom_info *info, uint8_t *rom, uint32_t size, memmap_chunk const *base_map, int base_chunks)
250{
251 uint32_t rom_end = get_u32be(rom + ROM_END) + 1;
252 if (size > rom_end) {
253 rom_end = size;
254 } else if (rom_end > nearest_pow2(size)) {
255 rom_end = nearest_pow2(size);
256 }
257 if (size >= 0x80000 && !memcmp("SEGA SSF", rom + 0x100, 8)) {
258 info->mapper_start_index = 0;
259 info->mapper_type = MAPPER_SEGA;
260 info->map_chunks = base_chunks + 9;
261 info->map = malloc(sizeof(memmap_chunk) * info->map_chunks);
262 memset(info->map, 0, sizeof(memmap_chunk)*9);
263 memcpy(info->map+9, base_map, sizeof(memmap_chunk) * base_chunks);
264
265 info->map[0].start = 0;
266 info->map[0].end = 0x80000;
267 info->map[0].mask = 0xFFFFFF;
268 info->map[0].flags = MMAP_READ;
269 info->map[0].buffer = rom;
270
271 if (has_ram_header(rom, size)){
272 read_ram_header(info, rom);
273 }
274
275 for (int i = 1; i < 8; i++)
276 {
277 info->map[i].start = i * 0x80000;
278 info->map[i].end = (i + 1) * 0x80000;
279 info->map[i].mask = 0x7FFFF;
280 info->map[i].buffer = (i + 1) * 0x80000 <= size ? rom + i * 0x80000 : rom;
281 info->map[i].ptr_index = i;
282 info->map[i].flags = MMAP_READ | MMAP_PTR_IDX | MMAP_CODE | MMAP_FUNC_NULL;
283
284 info->map[i].read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[i] == NULL
285 info->map[i].read_8 = (read_8_fun)read_sram_b;
286 info->map[i].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
287 info->map[i].write_8 = (write_8_fun)write_sram_area_b;
288
289 }
290 info->map[8].start = 0xA13000;
291 info->map[8].end = 0xA13100;
292 info->map[8].mask = 0xFF;
293 info->map[8].write_16 = (write_16_fun)write_bank_reg_w;
294 info->map[8].write_8 = (write_8_fun)write_bank_reg_b;
295 return;
296 } else if(!memcmp("SEGA MEGAWIFI", rom + 0x100, strlen("SEGA MEGAWIFI"))) {
297 info->mapper_type = MAPPER_NONE;
298 info->map_chunks = base_chunks + 2;
299 info->map = malloc(sizeof(memmap_chunk) * info->map_chunks);
300 memset(info->map, 0, sizeof(memmap_chunk)*2);
301 memcpy(info->map+2, base_map, sizeof(memmap_chunk) * base_chunks);
302 info->save_size = 0x400000;
303 info->save_bus = RAM_FLAG_BOTH;
304 info->save_type = SAVE_NOR;
305 info->map[0].start = 0;
306 info->map[0].end = 0x400000;
307 info->map[0].mask = 0xFFFFFF;
308 info->map[0].write_16 = nor_flash_write_w;
309 info->map[0].write_8 = nor_flash_write_b;
310 info->map[0].read_16 = nor_flash_read_w;
311 info->map[0].read_8 = nor_flash_read_b;
312 info->map[0].flags = MMAP_READ_CODE | MMAP_CODE;
313 info->map[0].buffer = info->save_buffer = malloc(info->save_size);
314 uint32_t init_size = size < info->save_size ? size : info->save_size;
315 memcpy(info->save_buffer, rom, init_size);
316 byteswap_rom(info->save_size, (uint16_t *)info->save_buffer);
317 info->nor = calloc(1, sizeof(nor_state));
318 nor_flash_init(info->nor, info->save_buffer, info->save_size, 128, 0xDA45, RAM_FLAG_BOTH);
319 info->nor->cmd_address1 = 0xAAB;
320 info->nor->cmd_address2 = 0x555;
321 info->map[1].start = 0xA130C0;
322 info->map[1].end = 0xA130D0;
323 info->map[1].mask = 0xFFFFFF;
324 if (!strcmp(
325 "on",
326 tern_find_path_default(config, "system\0megawifi\0", (tern_val){.ptrval="off"}, TVAL_PTR).ptrval)
327 ) {
328 info->map[1].write_16 = megawifi_write_w;
329 info->map[1].write_8 = megawifi_write_b;
330 info->map[1].read_16 = megawifi_read_w;
331 info->map[1].read_8 = megawifi_read_b;
332 } else {
333 warning("ROM uses MegaWiFi, but it is disabled\n");
334 }
335 return;
336 } else if (has_ram_header(rom, size)) {
337 uint32_t ram_start = read_ram_header(info, rom);
338
339 if (info->save_buffer) {
340 info->map_chunks = base_chunks + (ram_start >= rom_end ? 2 : 3);
341 info->map = malloc(sizeof(memmap_chunk) * info->map_chunks);
342 memset(info->map, 0, sizeof(memmap_chunk)*2);
343 memcpy(info->map+2, base_map, sizeof(memmap_chunk) * base_chunks);
344
345 if (ram_start >= rom_end) {
346 info->map[0].end = rom_end < 0x400000 ? nearest_pow2(rom_end) - 1 : 0xFFFFFF;
347 if (info->map[0].end > ram_start) {
348 info->map[0].end = ram_start;
349 }
350 //TODO: ROM mirroring
351 info->map[0].mask = 0xFFFFFF;
352 info->map[0].flags = MMAP_READ;
353 info->map[0].buffer = rom;
354
355 info->map[1].start = ram_start;
356 info->map[1].mask = info->save_mask;
357 info->map[1].end = ram_start + info->save_mask + 1;
358 info->map[1].flags = MMAP_READ | MMAP_WRITE;
359
360 if (info->save_type == RAM_FLAG_ODD) {
361 info->map[1].flags |= MMAP_ONLY_ODD;
362 } else if (info->save_type == RAM_FLAG_EVEN) {
363 info->map[1].flags |= MMAP_ONLY_EVEN;
364 }
365 info->map[1].buffer = info->save_buffer;
366 } else {
367 //Assume the standard Sega mapper
368 info->mapper_type = MAPPER_SEGA;
369 info->map[0].end = 0x200000;
370 info->map[0].mask = 0xFFFFFF;
371 info->map[0].flags = MMAP_READ;
372 info->map[0].buffer = rom;
373
374 info->map[1].start = 0x200000;
375 info->map[1].end = 0x400000;
376 info->map[1].mask = 0x1FFFFF;
377 info->map[1].flags = MMAP_READ | MMAP_PTR_IDX | MMAP_FUNC_NULL;
378 info->map[1].ptr_index = info->mapper_start_index = 0;
379 info->map[1].read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[2] == NULL
380 info->map[1].read_8 = (read_8_fun)read_sram_b;
381 info->map[1].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
382 info->map[1].write_8 = (write_8_fun)write_sram_area_b;
383 info->map[1].buffer = rom + 0x200000;
384
385 memmap_chunk *last = info->map + info->map_chunks - 1;
386 memset(last, 0, sizeof(memmap_chunk));
387 last->start = 0xA13000;
388 last->end = 0xA13100;
389 last->mask = 0xFF;
390 last->write_16 = (write_16_fun)write_bank_reg_w;
391 last->write_8 = (write_8_fun)write_bank_reg_b;
392 }
393 return;
394 }
395 }
396
397 info->map_chunks = base_chunks + 1;
398 info->map = malloc(sizeof(memmap_chunk) * info->map_chunks);
399 memset(info->map, 0, sizeof(memmap_chunk));
400 memcpy(info->map+1, base_map, sizeof(memmap_chunk) * base_chunks);
401
402 info->map[0].end = rom_end > 0x400000 ? rom_end : 0x400000;
403 info->map[0].mask = rom_end < 0x400000 ? nearest_pow2(rom_end) - 1 : 0xFFFFFF;
404 info->map[0].flags = MMAP_READ;
405 info->map[0].buffer = rom;
406 info->save_type = SAVE_NONE;
407}
408
409rom_info configure_rom_heuristics(uint8_t *rom, uint32_t rom_size, memmap_chunk const *base_map, uint32_t base_chunks)
410{
411 rom_info info;
412 info.mapper_type = MAPPER_NONE;
413 info.name = get_header_name(rom);
414 info.regions = get_header_regions(rom);
415 info.is_save_lock_on = 0;
416 info.rom = rom;
417 info.rom_size = rom_size;
418 add_memmap_header(&info, rom, rom_size, base_map, base_chunks);
419 info.port1_override = info.port2_override = info.ext_override = info.mouse_mode = NULL;
420 return info;
421}
422
423typedef struct {
424 rom_info *info;
425 uint8_t *rom;
426 uint8_t *lock_on;
427 tern_node *root;
428 tern_node *rom_db;
429 uint32_t rom_size;
430 uint32_t lock_on_size;
431 int index;
432 int num_els;
433 uint16_t ptr_index;
434} map_iter_state;
435
436void eeprom_read_fun(char *key, tern_val val, uint8_t valtype, void *data)
437{
438 int bit = atoi(key);
439 if (bit < 0 || bit > 15) {
440 fprintf(stderr, "bit %s is out of range", key);
441 return;
442 }
443 if (valtype != TVAL_PTR) {
444 fprintf(stderr, "bit %s has a non-scalar value", key);
445 return;
446 }
447 char *pin = val.ptrval;
448 if (strcmp(pin, "sda")) {
449 fprintf(stderr, "bit %s is connected to unrecognized read pin %s", key, pin);
450 return;
451 }
452 eeprom_map *map = data;
453 map->sda_read_bit = bit;
454}
455
456void eeprom_write_fun(char *key, tern_val val, uint8_t valtype, void *data)
457{
458 int bit = atoi(key);
459 if (bit < 0 || bit > 15) {
460 fprintf(stderr, "bit %s is out of range", key);
461 return;
462 }
463 if (valtype != TVAL_PTR) {
464 fprintf(stderr, "bit %s has a non-scalar value", key);
465 return;
466 }
467 char *pin = val.ptrval;
468 eeprom_map *map = data;
469 if (!strcmp(pin, "sda")) {
470 map->sda_write_mask = 1 << bit;
471 return;
472 }
473 if (!strcmp(pin, "scl")) {
474 map->scl_mask = 1 << bit;
475 return;
476 }
477 fprintf(stderr, "bit %s is connected to unrecognized write pin %s", key, pin);
478}
479
480void process_sram_def(char *key, map_iter_state *state)
481{
482 if (!state->info->save_size) {
483 char * size = tern_find_path(state->root, "SRAM\0size\0", TVAL_PTR).ptrval;
484 if (!size) {
485 fatal_error("ROM DB map entry %d with address %s has device type SRAM, but the SRAM size is not defined\n", state->index, key);
486 }
487 state->info->save_size = atoi(size);
488 if (!state->info->save_size) {
489 fatal_error("SRAM size %s is invalid\n", size);
490 }
491 state->info->save_mask = nearest_pow2(state->info->save_size)-1;
492 state->info->save_buffer = malloc(state->info->save_size);
493 memset(state->info->save_buffer, 0, state->info->save_size);
494 char *bus = tern_find_path(state->root, "SRAM\0bus\0", TVAL_PTR).ptrval;
495 if (!strcmp(bus, "odd")) {
496 state->info->save_type = RAM_FLAG_ODD;
497 } else if(!strcmp(bus, "even")) {
498 state->info->save_type = RAM_FLAG_EVEN;
499 } else {
500 state->info->save_type = RAM_FLAG_BOTH;
501 }
502 }
503}
504
505void process_eeprom_def(char * key, map_iter_state *state)
506{
507 if (!state->info->save_size) {
508 char * size = tern_find_path(state->root, "EEPROM\0size\0", TVAL_PTR).ptrval;
509 if (!size) {
510 fatal_error("ROM DB map entry %d with address %s has device type EEPROM, but the EEPROM size is not defined\n", state->index, key);
511 }
512 state->info->save_size = atoi(size);
513 if (!state->info->save_size) {
514 fatal_error("EEPROM size %s is invalid\n", size);
515 }
516 char *etype = tern_find_path(state->root, "EEPROM\0type\0", TVAL_PTR).ptrval;
517 if (!etype) {
518 etype = "i2c";
519 }
520 if (!strcmp(etype, "i2c")) {
521 state->info->save_type = SAVE_I2C;
522 } else {
523 fatal_error("EEPROM type %s is invalid\n", etype);
524 }
525 state->info->save_buffer = malloc(state->info->save_size);
526 memset(state->info->save_buffer, 0xFF, state->info->save_size);
527 state->info->eeprom_map = malloc(sizeof(eeprom_map) * state->num_els);
528 memset(state->info->eeprom_map, 0, sizeof(eeprom_map) * state->num_els);
529 }
530}
531
532void process_nor_def(char *key, map_iter_state *state)
533{
534 if (!state->info->save_size) {
535 char *size = tern_find_path(state->root, "NOR\0size\0", TVAL_PTR).ptrval;
536 if (!size) {
537 fatal_error("ROM DB map entry %d with address %s has device type NOR, but the NOR size is not defined\n", state->index, key);
538 }
539 state->info->save_size = atoi(size);
540 if (!state->info->save_size) {
541 fatal_error("NOR size %s is invalid\n", size);
542 }
543 char *page_size = tern_find_path(state->root, "NOR\0page_size\0", TVAL_PTR).ptrval;
544 if (!page_size) {
545 fatal_error("ROM DB map entry %d with address %s has device type NOR, but the NOR page size is not defined\n", state->index, key);
546 }
547 uint32_t save_page_size = atoi(page_size);
548 if (!save_page_size) {
549 fatal_error("NOR page size %s is invalid\n", page_size);
550 }
551 char *product_id = tern_find_path(state->root, "NOR\0product_id\0", TVAL_PTR).ptrval;
552 if (!product_id) {
553 fatal_error("ROM DB map entry %d with address %s has device type NOR, but the NOR product ID is not defined\n", state->index, key);
554 }
555 uint16_t save_product_id = strtol(product_id, NULL, 16);
556 char *bus = tern_find_path(state->root, "NOR\0bus\0", TVAL_PTR).ptrval;
557 if (!strcmp(bus, "odd")) {
558 state->info->save_bus = RAM_FLAG_ODD;
559 } else if(!strcmp(bus, "even")) {
560 state->info->save_bus = RAM_FLAG_EVEN;
561 } else {
562 state->info->save_bus = RAM_FLAG_BOTH;
563 }
564 state->info->save_type = SAVE_NOR;
565 state->info->save_buffer = malloc(state->info->save_size);
566 char *init = tern_find_path_default(state->root, "NOR\0init\0", (tern_val){.ptrval="FF"}, TVAL_PTR).ptrval;
567 if (!strcmp(init, "ROM")) {
568 uint32_t init_size = state->rom_size > state->info->save_size ? state->info->save_size : state->rom_size;
569 memcpy(state->info->save_buffer, state->rom, init_size);
570 if (state->info->save_bus == RAM_FLAG_BOTH) {
571 byteswap_rom(state->info->save_size, (uint16_t *)state->info->save_buffer);
572 }
573 } else {
574 memset(state->info->save_buffer, strtol(init, NULL, 16), state->info->save_size);
575 }
576 state->info->nor = calloc(1, sizeof(nor_state));
577 nor_flash_init(state->info->nor, state->info->save_buffer, state->info->save_size, save_page_size, save_product_id, state->info->save_bus);
578 char *cmd1 = tern_find_path(state->root, "NOR\0cmd_address1\0", TVAL_PTR).ptrval;
579 if (cmd1) {
580 state->info->nor->cmd_address1 = strtol(cmd1, NULL, 16);
581 }
582 char *cmd2 = tern_find_path(state->root, "NOR\0cmd_address2\0", TVAL_PTR).ptrval;
583 if (cmd2) {
584 state->info->nor->cmd_address2 = strtol(cmd2, NULL, 16);
585 }
586 }
587}
588
589void add_eeprom_map(tern_node *node, uint32_t start, uint32_t end, map_iter_state *state)
590{
591 eeprom_map *eep_map = state->info->eeprom_map + state->info->num_eeprom;
592 eep_map->start = start;
593 eep_map->end = end;
594 eep_map->sda_read_bit = 0xFF;
595 tern_node * bits_read = tern_find_node(node, "bits_read");
596 if (bits_read) {
597 tern_foreach(bits_read, eeprom_read_fun, eep_map);
598 }
599 tern_node * bits_write = tern_find_node(node, "bits_write");
600 if (bits_write) {
601 tern_foreach(bits_write, eeprom_write_fun, eep_map);
602 }
603 debug_message("EEPROM address %X: sda read: %X, sda write: %X, scl: %X\n", start, eep_map->sda_read_bit, eep_map->sda_write_mask, eep_map->scl_mask);
604 state->info->num_eeprom++;
605}
606
607void map_iter_fun(char *key, tern_val val, uint8_t valtype, void *data)
608{
609 map_iter_state *state = data;
610 if (valtype != TVAL_NODE) {
611 fatal_error("ROM DB map entry %d with address %s is not a node\n", state->index, key);
612 }
613 tern_node *node = val.ptrval;
614 uint32_t start = strtol(key, NULL, 16);
615 uint32_t end = strtol(tern_find_ptr_default(node, "last", "0"), NULL, 16);
616 if (!end || end < start) {
617 fatal_error("'last' value is missing or invalid for ROM DB map entry %d with address %s\n", state->index, key);
618 }
619 char * dtype = tern_find_ptr_default(node, "device", "ROM");
620 uint32_t offset = strtol(tern_find_ptr_default(node, "offset", "0"), NULL, 16);
621 memmap_chunk *map = state->info->map + state->index;
622 map->start = start;
623 map->end = end + 1;
624 if (!strcmp(dtype, "ROM")) {
625 map->buffer = state->rom + offset;
626 map->mask = calc_mask(state->rom_size - offset, start, end);
627 if (strcmp(tern_find_ptr_default(node, "writeable", "no"), "yes")) {
628 map->flags = MMAP_READ;
629 } else {
630 map->flags = MMAP_READ | MMAP_WRITE | MMAP_CODE;
631 }
632 } else if (!strcmp(dtype, "LOCK-ON")) {
633 rom_info lock_info;
634 if (state->lock_on) {
635 lock_info = configure_rom(state->rom_db, state->lock_on, state->lock_on_size, NULL, 0, NULL, 0);
636 } else if (state->rom_size > start) {
637 //This is a bit of a hack to deal with pre-combined S3&K/S2&K ROMs and S&K ROM hacks
638 lock_info = configure_rom(state->rom_db, state->rom + start, state->rom_size - start, NULL, 0, NULL, 0);
639 } else {
640 //skip this entry if there is no lock on cartridge attached
641 return;
642 }
643 uint32_t matching_chunks = 0;
644 for (int i = 0; i < lock_info.map_chunks; i++)
645 {
646 if (lock_info.map[i].start < 0xC00000 && lock_info.map[i].end > 0x200000) {
647 matching_chunks++;
648 }
649 }
650 if (matching_chunks == 0) {
651 //Nothing mapped in the relevant range for the lock-on cart, ignore this mapping
652 free_rom_info(&lock_info);
653 return;
654 } else if (matching_chunks > 1) {
655 state->info->map_chunks += matching_chunks - 1;
656 state->info->map = realloc(state->info->map, sizeof(memmap_chunk) * state->info->map_chunks);
657 memset(state->info->map + state->info->map_chunks - (matching_chunks - 1), 0, sizeof(memmap_chunk) * (matching_chunks - 1));
658 map = state->info->map + state->index;
659 }
660 for (int i = 0; i < lock_info.map_chunks; i++)
661 {
662 if (lock_info.map[i].start >= 0xC00000 || lock_info.map[i].end <= 0x200000) {
663 continue;
664 }
665 *map = lock_info.map[i];
666 if (map->start < 0x200000) {
667 if (map->buffer) {
668 map->buffer += (0x200000 - map->start) & ((map->flags & MMAP_AUX_BUFF) ? map->aux_mask : map->mask);
669 }
670 map->start = 0x200000;
671 }
672 map++;
673 state->index++;
674 }
675 if (state->info->save_type == SAVE_NONE && lock_info.save_type != SAVE_NONE) {
676 //main cart has no save device, but lock-on cart does
677 if (state->lock_on) {
678 state->info->is_save_lock_on = 1;
679 }
680 state->info->save_buffer = lock_info.save_buffer;
681 state->info->save_size = lock_info.save_size;
682 state->info->save_mask = lock_info.save_mask;
683 state->info->nor = lock_info.nor;
684 state->info->save_type = lock_info.save_type;
685 state->info->save_bus = lock_info.save_bus;
686 lock_info.save_buffer = NULL;
687 lock_info.save_type = SAVE_NONE;
688 }
689 free_rom_info(&lock_info);
690 return;
691 } else if (!strcmp(dtype, "EEPROM")) {
692 process_eeprom_def(key, state);
693 add_eeprom_map(node, start, end, state);
694
695 map->write_16 = write_eeprom_i2c_w;
696 map->write_8 = write_eeprom_i2c_b;
697 map->read_16 = read_eeprom_i2c_w;
698 map->read_8 = read_eeprom_i2c_b;
699 map->mask = 0xFFFFFF;
700 } else if (!strcmp(dtype, "SRAM")) {
701 process_sram_def(key, state);
702 map->buffer = state->info->save_buffer + offset;
703 map->flags = MMAP_READ | MMAP_WRITE;
704 if (state->info->save_type == RAM_FLAG_ODD) {
705 map->flags |= MMAP_ONLY_ODD;
706 } else if(state->info->save_type == RAM_FLAG_EVEN) {
707 map->flags |= MMAP_ONLY_EVEN;
708 }
709 map->mask = calc_mask(state->info->save_size, start, end);
710 } else if (!strcmp(dtype, "RAM")) {
711 uint32_t size = strtol(tern_find_ptr_default(node, "size", "0"), NULL, 16);
712 if (!size || size > map->end - map->start) {
713 size = map->end - map->start;
714 }
715 map->buffer = malloc(size);
716 map->mask = calc_mask(size, start, end);
717 map->flags = MMAP_READ | MMAP_WRITE;
718 char *bus = tern_find_ptr_default(node, "bus", "both");
719 if (!strcmp(bus, "odd")) {
720 map->flags |= MMAP_ONLY_ODD;
721 } else if (!strcmp(bus, "even")) {
722 map->flags |= MMAP_ONLY_EVEN;
723 } else {
724 map->flags |= MMAP_CODE;
725 }
726 } else if (!strcmp(dtype, "NOR")) {
727 process_nor_def(key, state);
728
729 map->write_16 = nor_flash_write_w;
730 map->write_8 = nor_flash_write_b;
731 map->read_16 = nor_flash_read_w;
732 map->read_8 = nor_flash_read_b;
733 if (state->info->save_bus == RAM_FLAG_BOTH) {
734 map->flags |= MMAP_READ_CODE | MMAP_CODE;
735 map->buffer = state->info->save_buffer;
736 }
737 map->mask = 0xFFFFFF;
738 } else if (!strcmp(dtype, "Sega mapper")) {
739 state->info->mapper_type = MAPPER_SEGA;
740 state->info->mapper_start_index = state->ptr_index++;
741 char *variant = tern_find_ptr_default(node, "variant", "full");
742 char *save_device = tern_find_path(node, "save\0device\0", TVAL_PTR).ptrval;
743 if (save_device && !strcmp(save_device, "EEPROM")) {
744 process_eeprom_def(key, state);
745 add_eeprom_map(node, start & map->mask, end & map->mask, state);
746 } else if (save_device && !strcmp(save_device, "SRAM")) {
747 process_sram_def(key, state);
748 } else if(has_ram_header(state->rom, state->rom_size)) {
749 //no save definition in ROM DB entry, but there is an SRAM header
750 //this support is mostly to handle homebrew that uses the SSF2 product ID
751 //in an attempt to signal desire for the full Sega/SSF2 mapper, but also uses SRAM unlike SSF2
752 read_ram_header(state->info, state->rom);
753 }
754 if (!strcmp(variant, "save-only")) {
755 state->info->map_chunks+=1;
756 state->info->map = realloc(state->info->map, sizeof(memmap_chunk) * state->info->map_chunks);
757 memset(state->info->map + state->info->map_chunks - 1, 0, sizeof(memmap_chunk) * 1);
758 map = state->info->map + state->index;
759 map->start = start;
760 map->end = end;
761 offset &= nearest_pow2(state->rom_size) - 1;
762 map->buffer = state->rom + offset;
763 map->mask = calc_mask(state->rom_size - offset, start, end);
764 map->ptr_index = state->info->mapper_start_index;
765 map->flags = MMAP_READ | MMAP_PTR_IDX | MMAP_CODE | MMAP_FUNC_NULL;
766 if (save_device && !strcmp(save_device, "EEPROM")) {
767 map->write_16 = write_eeprom_i2c_w;
768 map->write_8 = write_eeprom_i2c_b;
769 map->read_16 = read_eeprom_i2c_w;
770 map->read_8 = read_eeprom_i2c_b;
771 } else {
772 map->read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[ptr_idx] == NULL
773 map->read_8 = (read_8_fun)read_sram_b;
774 map->write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
775 map->write_8 = (write_8_fun)write_sram_area_b;
776 }
777 state->index++;
778 map++;
779 } else {
780 state->info->map_chunks+=7;
781 state->info->map = realloc(state->info->map, sizeof(memmap_chunk) * state->info->map_chunks);
782 memset(state->info->map + state->info->map_chunks - 7, 0, sizeof(memmap_chunk) * 7);
783 map = state->info->map + state->index;
784 for (int i = 0; i < 7; i++, state->index++, map++)
785 {
786 map->start = start + i * 0x80000;
787 map->end = start + (i + 1) * 0x80000;
788 map->mask = 0x7FFFF;
789 map->buffer = state->rom + offset + i * 0x80000;
790 map->ptr_index = state->ptr_index++;
791 if (i < 3) {
792 map->flags = MMAP_READ | MMAP_PTR_IDX | MMAP_CODE;
793 } else {
794 map->flags = MMAP_READ | MMAP_PTR_IDX | MMAP_CODE | MMAP_FUNC_NULL;
795 if (save_device && !strcmp(save_device, "EEPROM")) {
796 map->write_16 = write_eeprom_i2c_w;
797 map->write_8 = write_eeprom_i2c_b;
798 map->read_16 = read_eeprom_i2c_w;
799 map->read_8 = read_eeprom_i2c_b;
800 } else {
801 map->read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[2] == NULL
802 map->read_8 = (read_8_fun)read_sram_b;
803 map->write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
804 map->write_8 = (write_8_fun)write_sram_area_b;
805 }
806 }
807 }
808 }
809 map->start = 0xA13000;
810 map->end = 0xA13100;
811 map->mask = 0xFF;
812 map->write_16 = (write_16_fun)write_bank_reg_w;
813 map->write_8 = (write_8_fun)write_bank_reg_b;
814 } else if (!strcmp(dtype, "MENU")) {
815 //fake hardware for supporting menu
816 map->buffer = NULL;
817 map->mask = 0xFF;
818 map->write_16 = menu_write_w;
819 map->read_16 = menu_read_w;
820 } else if (!strcmp(dtype, "fixed")) {
821 uint16_t *value = malloc(2);
822 map->buffer = value;
823 map->mask = 0;
824 map->flags = MMAP_READ;
825 *value = strtol(tern_find_ptr_default(node, "value", "0"), NULL, 16);
826 } else if (!strcmp(dtype, "multi-game")) {
827 state->info->mapper_type = MAPPER_MULTI_GAME;
828 state->info->mapper_start_index = state->ptr_index++;
829 //make a mirror copy of the ROM so we can efficiently support arbitrary start offsets
830 state->rom = realloc(state->rom, state->rom_size * 2);
831 memcpy(state->rom + state->rom_size, state->rom, state->rom_size);
832 state->rom_size *= 2;
833 //make room for an extra map entry
834 state->info->map_chunks+=1;
835 state->info->map = realloc(state->info->map, sizeof(memmap_chunk) * state->info->map_chunks);
836 memset(state->info->map + state->info->map_chunks - 1, 0, sizeof(memmap_chunk) * 1);
837 map = state->info->map + state->index;
838 map->buffer = state->rom;
839 map->mask = calc_mask(state->rom_size, start, end);
840 map->flags = MMAP_READ | MMAP_PTR_IDX | MMAP_CODE;
841 map->ptr_index = state->info->mapper_start_index;
842 map++;
843 state->index++;
844 map->start = 0xA13000;
845 map->end = 0xA13100;
846 map->mask = 0xFF;
847 map->write_16 = write_multi_game_w;
848 map->write_8 = write_multi_game_b;
849 } else if (!strcmp(dtype, "megawifi")) {
850 if (!strcmp(
851 "on",
852 tern_find_path_default(config, "system\0megawifi\0", (tern_val){.ptrval="off"}, TVAL_PTR).ptrval)
853 ) {
854 map->write_16 = megawifi_write_w;
855 map->write_8 = megawifi_write_b;
856 map->read_16 = megawifi_read_w;
857 map->read_8 = megawifi_read_b;
858 map->mask = 0xFFFFFF;
859 } else {
860 warning("ROM uses MegaWiFi, but it is disabled\n");
861 return;
862 }
863 } else if (!strcmp(dtype, "jcart")) {
864 state->info->mapper_type = MAPPER_JCART;
865 map->write_16 = jcart_write_w;
866 map->write_8 = jcart_write_b;
867 map->read_16 = jcart_read_w;
868 map->read_8 = jcart_read_b;
869 map->mask = 0xFFFFFF;
870 } else {
871 fatal_error("Invalid device type %s for ROM DB map entry %d with address %s\n", dtype, state->index, key);
872 }
873 state->index++;
874}
875
876rom_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)
877{
878 uint8_t product_id[GAME_ID_LEN+1];
879 uint8_t *rom = vrom;
880 product_id[GAME_ID_LEN] = 0;
881 for (int i = 0; i < GAME_ID_LEN; i++)
882 {
883 if (rom[GAME_ID_OFF + i] <= ' ') {
884 product_id[i] = 0;
885 break;
886 }
887 product_id[i] = rom[GAME_ID_OFF + i];
888
889 }
890 debug_message("Product ID: %s\n", product_id);
891 uint8_t raw_hash[20];
892 sha1(vrom, rom_size, raw_hash);
893 uint8_t hex_hash[41];
894 bin_to_hex(hex_hash, raw_hash, 20);
895 debug_message("SHA1: %s\n", hex_hash);
896 tern_node * entry = tern_find_node(rom_db, hex_hash);
897 if (!entry) {
898 entry = tern_find_node(rom_db, product_id);
899 }
900 if (!entry) {
901 debug_message("Not found in ROM DB, examining header\n\n");
902 if (xband_detect(rom, rom_size)) {
903 return xband_configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, base_chunks);
904 }
905 if (realtec_detect(rom, rom_size)) {
906 return realtec_configure_rom(rom, rom_size, base_map, base_chunks);
907 }
908 return configure_rom_heuristics(rom, rom_size, base_map, base_chunks);
909 }
910 rom_info info;
911 info.mapper_type = MAPPER_NONE;
912 info.name = tern_find_ptr(entry, "name");
913 if (info.name) {
914 debug_message("Found name: %s\n\n", info.name);
915 info.name = strdup(info.name);
916 } else {
917 info.name = get_header_name(rom);
918 }
919
920 char *dbreg = tern_find_ptr(entry, "regions");
921 info.regions = 0;
922 if (dbreg) {
923 while (*dbreg != 0)
924 {
925 info.regions |= translate_region_char(*(dbreg++));
926 }
927 }
928 if (!info.regions) {
929 info.regions = get_header_regions(rom);
930 }
931
932 info.is_save_lock_on = 0;
933 info.rom = vrom;
934 info.rom_size = rom_size;
935 tern_node *map = tern_find_node(entry, "map");
936 if (map) {
937 info.save_type = SAVE_NONE;
938 info.map_chunks = tern_count(map);
939 if (info.map_chunks) {
940 info.map_chunks += base_chunks;
941 info.save_buffer = NULL;
942 info.save_size = 0;
943 info.map = malloc(sizeof(memmap_chunk) * info.map_chunks);
944 info.eeprom_map = NULL;
945 info.num_eeprom = 0;
946 memset(info.map, 0, sizeof(memmap_chunk) * info.map_chunks);
947 map_iter_state state = {
948 .info = &info,
949 .rom = rom,
950 .lock_on = lock_on,
951 .root = entry,
952 .rom_db = rom_db,
953 .rom_size = rom_size,
954 .lock_on_size = lock_on_size,
955 .index = 0,
956 .num_els = info.map_chunks - base_chunks,
957 .ptr_index = 0
958 };
959 tern_foreach(map, map_iter_fun, &state);
960 memcpy(info.map + state.index, base_map, sizeof(memmap_chunk) * base_chunks);
961 info.rom = state.rom;
962 info.rom_size = state.rom_size;
963 } else {
964 add_memmap_header(&info, rom, rom_size, base_map, base_chunks);
965 }
966 } else {
967 add_memmap_header(&info, rom, rom_size, base_map, base_chunks);
968 }
969
970 tern_node *device_overrides = tern_find_node(entry, "device_overrides");
971 if (device_overrides) {
972 info.port1_override = tern_find_ptr(device_overrides, "1");
973 info.port2_override = tern_find_ptr(device_overrides, "2");
974 info.ext_override = tern_find_ptr(device_overrides, "ext");
975 } else {
976 info.port1_override = info.port2_override = info.ext_override = NULL;
977 }
978 info.mouse_mode = tern_find_ptr(entry, "mouse_mode");
979
980 return info;
981}