comparison romdb.c @ 2053:3414a4423de1 segacd

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 15 Jan 2022 13:15:21 -0800
parents 5dacaef602a7 3748a2a8a4b7
children 8ee7ecbf3f21
comparison
equal deleted inserted replaced
1692:5dacaef602a7 2053:3414a4423de1
30 { 30 {
31 if (save_type == SAVE_I2C) { 31 if (save_type == SAVE_I2C) {
32 return "EEPROM"; 32 return "EEPROM";
33 } else if(save_type == SAVE_NOR) { 33 } else if(save_type == SAVE_NOR) {
34 return "NOR Flash"; 34 return "NOR Flash";
35 } else if(save_type == SAVE_HBPT) {
36 return "Heartbeat Personal Trainer";
35 } 37 }
36 return "SRAM"; 38 return "SRAM";
37 } 39 }
38 40
39 tern_node *get_rom_db() 41 tern_node *get_rom_db()
78 start_section(buf, SECTION_MAPPER); 80 start_section(buf, SECTION_MAPPER);
79 save_int8(buf, gen->mapper_type); 81 save_int8(buf, gen->mapper_type);
80 switch(gen->mapper_type) 82 switch(gen->mapper_type)
81 { 83 {
82 case MAPPER_SEGA: 84 case MAPPER_SEGA:
85 case MAPPER_SEGA_SRAM:
86 case MAPPER_SEGA_MED_V2:
83 sega_mapper_serialize(gen, buf); 87 sega_mapper_serialize(gen, buf);
84 break; 88 break;
85 case MAPPER_REALTEC: 89 case MAPPER_REALTEC:
86 realtec_serialize(gen, buf); 90 realtec_serialize(gen, buf);
87 break; 91 break;
97 101
98 void cart_deserialize(deserialize_buffer *buf, void *vcontext) 102 void cart_deserialize(deserialize_buffer *buf, void *vcontext)
99 { 103 {
100 genesis_context *gen = vcontext; 104 genesis_context *gen = vcontext;
101 uint8_t mapper_type = load_int8(buf); 105 uint8_t mapper_type = load_int8(buf);
102 if (mapper_type != gen->mapper_type) { 106 if (mapper_type != gen->mapper_type && (mapper_type != MAPPER_SEGA || gen->mapper_type != MAPPER_SEGA_SRAM)) {
103 warning("Mapper type mismatch, skipping load of mapper state"); 107 warning("Mapper type mismatch, skipping load of mapper state\n");
104 return; 108 return;
105 } 109 }
106 switch(gen->mapper_type) 110 switch(gen->mapper_type)
107 { 111 {
108 case MAPPER_SEGA: 112 case MAPPER_SEGA:
113 case MAPPER_SEGA_SRAM:
109 sega_mapper_deserialize(buf, gen); 114 sega_mapper_deserialize(buf, gen);
110 break; 115 break;
111 case MAPPER_REALTEC: 116 case MAPPER_REALTEC:
112 realtec_deserialize(buf, gen); 117 realtec_deserialize(buf, gen);
113 break; 118 break;
123 char *get_header_name(uint8_t *rom) 128 char *get_header_name(uint8_t *rom)
124 { 129 {
125 //TODO: Should probably prefer the title field that corresponds to the user's region preference 130 //TODO: Should probably prefer the title field that corresponds to the user's region preference
126 uint8_t *last = rom + TITLE_END - 1; 131 uint8_t *last = rom + TITLE_END - 1;
127 uint8_t *src = rom + TITLE_START; 132 uint8_t *src = rom + TITLE_START;
128 133
129 for (;;) 134 for (;;)
130 { 135 {
131 while (last > src && (*last <= 0x20 || *last >= 0x80)) 136 while (last > src && (*last <= 0x20 || *last >= 0x80))
132 { 137 {
133 last--; 138 last--;
166 171
167 char *region_chars = "JUEW"; 172 char *region_chars = "JUEW";
168 uint8_t region_bits[] = {REGION_J, REGION_U, REGION_E, REGION_J|REGION_U|REGION_E}; 173 uint8_t region_bits[] = {REGION_J, REGION_U, REGION_E, REGION_J|REGION_U|REGION_E};
169 174
170 uint8_t translate_region_char(uint8_t c) 175 uint8_t translate_region_char(uint8_t c)
171 { 176 {
172 for (int i = 0; i < sizeof(region_bits); i++) 177 for (int i = 0; i < sizeof(region_bits); i++)
173 { 178 {
174 if (c == region_chars[i]) { 179 if (c == region_chars[i]) {
175 return region_bits[i]; 180 return region_bits[i];
176 } 181 }
223 } 228 }
224 } 229 }
225 230
226 uint8_t has_ram_header(uint8_t *rom, uint32_t rom_size) 231 uint8_t has_ram_header(uint8_t *rom, uint32_t rom_size)
227 { 232 {
228 return rom_size >= (RAM_END + 4) && rom[RAM_ID] == 'R' && rom[RAM_ID + 1] == 'A'; 233 return rom_size >= (RAM_END + 4) && rom[RAM_ID] == 'R' && rom[RAM_ID + 1] == 'A';
229 } 234 }
230 235
231 uint32_t read_ram_header(rom_info *info, uint8_t *rom) 236 uint32_t read_ram_header(rom_info *info, uint8_t *rom)
232 { 237 {
233 uint32_t ram_start = get_u32be(rom + RAM_START); 238 uint32_t ram_start = get_u32be(rom + RAM_START);
243 uint32_t save_size = info->save_mask + 1; 248 uint32_t save_size = info->save_mask + 1;
244 if (ram_flags != RAM_FLAG_BOTH) { 249 if (ram_flags != RAM_FLAG_BOTH) {
245 save_size /= 2; 250 save_size /= 2;
246 } 251 }
247 info->save_size = save_size; 252 info->save_size = save_size;
248 info->save_buffer = malloc(save_size); 253 info->save_buffer = calloc(save_size, 1);
249 return ram_start; 254 return ram_start;
250 } 255 }
251 256
252 void add_memmap_header(rom_info *info, uint8_t *rom, uint32_t size, memmap_chunk const *base_map, int base_chunks) 257 void add_memmap_header(rom_info *info, uint8_t *rom, uint32_t size, memmap_chunk const *base_map, int base_chunks)
253 { 258 {
254 uint32_t rom_end = get_u32be(rom + ROM_END) + 1; 259 uint32_t rom_end = get_u32be(rom + ROM_END) + 1;
260 uint32_t rom_end_raw = rom_end;
255 if (size > rom_end) { 261 if (size > rom_end) {
256 rom_end = size; 262 rom_end = size;
257 } else if (rom_end > nearest_pow2(size)) { 263 } else if (rom_end > nearest_pow2(size)) {
258 rom_end = nearest_pow2(size); 264 rom_end = nearest_pow2(size);
259 } 265 }
260 if (size >= 0x80000 && !memcmp("SEGA SSF", rom + 0x100, 8)) { 266 info->save_type = SAVE_NONE;
267 uint8_t is_med_ssf = size >= 0x108 && !memcmp("SEGA SSF", rom + 0x100, 8);
268 if (is_med_ssf || (size >= 0x400000 && rom_end_raw <= 0x400000)) {
269 if (is_med_ssf && rom_end < 16*1024*1024) {
270 info->rom = rom = realloc(rom, 16*1024*1024);
271 }
261 info->mapper_start_index = 0; 272 info->mapper_start_index = 0;
262 info->mapper_type = MAPPER_SEGA; 273 info->mapper_type = is_med_ssf ? MAPPER_SEGA_MED_V2 : MAPPER_SEGA;
263 info->map_chunks = base_chunks + 9; 274 info->map_chunks = base_chunks + 9;
264 info->map = malloc(sizeof(memmap_chunk) * info->map_chunks); 275 info->map = malloc(sizeof(memmap_chunk) * info->map_chunks);
265 memset(info->map, 0, sizeof(memmap_chunk)*9); 276 memset(info->map, 0, sizeof(memmap_chunk)*9);
266 memcpy(info->map+9, base_map, sizeof(memmap_chunk) * base_chunks); 277 memcpy(info->map+9, base_map, sizeof(memmap_chunk) * base_chunks);
267 278
268 info->map[0].start = 0; 279 int i;
269 info->map[0].end = 0x80000; 280 uint16_t map_flags;
270 info->map[0].mask = 0xFFFFFF; 281 if (is_med_ssf) {
271 info->map[0].flags = MMAP_READ; 282 i = 0;
272 info->map[0].buffer = rom; 283 map_flags = info->map[i].flags = MMAP_READ | MMAP_PTR_IDX | MMAP_CODE;
273 284 info->save_type = RAM_FLAG_BOTH;
274 if (has_ram_header(rom, size)){ 285 info->save_size = 256*1024;
275 read_ram_header(info, rom); 286 info->save_mask = info->save_size - 1;
276 } 287 info->save_buffer = rom + 16*1024*1024 - 256*1024;
277 288 } else {
278 for (int i = 1; i < 8; i++) 289 i = 1;
290 map_flags = info->map[i].flags = MMAP_READ | MMAP_PTR_IDX | MMAP_CODE | MMAP_FUNC_NULL;
291 info->map[0].start = 0;
292 info->map[0].end = 0x80000;
293 info->map[0].mask = 0xFFFFFF;
294 info->map[0].flags = MMAP_READ;
295 info->map[0].buffer = rom;
296
297 if (has_ram_header(rom, size)){
298 read_ram_header(info, rom);
299 }
300 }
301 static const write_8_fun med_w8[] = {
302 write_med_ram0_b,
303 write_med_ram1_b,
304 write_med_ram2_b,
305 write_med_ram3_b,
306 write_med_ram4_b,
307 write_med_ram5_b,
308 write_med_ram6_b,
309 write_med_ram7_b,
310 };
311 static const write_16_fun med_w16[] = {
312 write_med_ram0_w,
313 write_med_ram1_w,
314 write_med_ram2_w,
315 write_med_ram3_w,
316 write_med_ram4_w,
317 write_med_ram5_w,
318 write_med_ram6_w,
319 write_med_ram7_w,
320 };
321
322 for (; i < 8; i++)
279 { 323 {
280 info->map[i].start = i * 0x80000; 324 info->map[i].start = i * 0x80000;
281 info->map[i].end = (i + 1) * 0x80000; 325 info->map[i].end = (i + 1) * 0x80000;
282 info->map[i].mask = 0x7FFFF; 326 info->map[i].mask = 0x7FFFF;
283 info->map[i].buffer = (i + 1) * 0x80000 <= size ? rom + i * 0x80000 : rom; 327 info->map[i].buffer = (i + 1) * 0x80000 <= size ? rom + i * 0x80000 : rom;
284 info->map[i].ptr_index = i; 328 info->map[i].ptr_index = i;
285 info->map[i].flags = MMAP_READ | MMAP_PTR_IDX | MMAP_CODE | MMAP_FUNC_NULL; 329 info->map[i].flags = map_flags;
286 330
287 info->map[i].read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[i] == NULL 331 info->map[i].read_16 = is_med_ssf ? NULL : (read_16_fun)read_sram_w;//these will only be called when mem_pointers[i] == NULL
288 info->map[i].read_8 = (read_8_fun)read_sram_b; 332 info->map[i].read_8 = is_med_ssf ? NULL : (read_8_fun)read_sram_b;
289 info->map[i].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area 333 if (is_med_ssf) {
290 info->map[i].write_8 = (write_8_fun)write_sram_area_b; 334 info->map[i].write_16 = med_w16[i];
291 335 info->map[i].write_8 = med_w8[i];
336 } else {
337 info->map[i].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
338 info->map[i].write_8 = (write_8_fun)write_sram_area_b;
339 }
292 } 340 }
293 info->map[8].start = 0xA13000; 341 info->map[8].start = 0xA13000;
294 info->map[8].end = 0xA13100; 342 info->map[8].end = 0xA13100;
295 info->map[8].mask = 0xFF; 343 info->map[8].mask = 0xFF;
296 info->map[8].write_16 = (write_16_fun)write_bank_reg_w; 344 info->map[8].write_16 = (write_16_fun)write_bank_reg_w;
297 info->map[8].write_8 = (write_8_fun)write_bank_reg_b; 345 info->map[8].write_8 = (write_8_fun)write_bank_reg_b;
346 return;
347 } else if(!memcmp("SEGA MEGAWIFI", rom + 0x100, strlen("SEGA MEGAWIFI"))) {
348 info->mapper_type = MAPPER_NONE;
349 info->map_chunks = base_chunks + 2;
350 info->map = malloc(sizeof(memmap_chunk) * info->map_chunks);
351 memset(info->map, 0, sizeof(memmap_chunk)*2);
352 memcpy(info->map+2, base_map, sizeof(memmap_chunk) * base_chunks);
353 info->save_size = 0x400000;
354 info->save_bus = RAM_FLAG_BOTH;
355 info->save_type = SAVE_NOR;
356 info->map[0].start = 0;
357 info->map[0].end = 0x400000;
358 info->map[0].mask = 0xFFFFFF;
359 info->map[0].write_16 = nor_flash_write_w;
360 info->map[0].write_8 = nor_flash_write_b;
361 info->map[0].read_16 = nor_flash_read_w;
362 info->map[0].read_8 = nor_flash_read_b;
363 info->map[0].flags = MMAP_READ_CODE | MMAP_CODE;
364 info->map[0].buffer = info->save_buffer = calloc(info->save_size, 1);
365 uint32_t init_size = size < info->save_size ? size : info->save_size;
366 memcpy(info->save_buffer, rom, init_size);
367 byteswap_rom(info->save_size, (uint16_t *)info->save_buffer);
368 info->nor = calloc(1, sizeof(nor_state));
369 nor_flash_init(info->nor, info->save_buffer, info->save_size, 128, 0xDA45, RAM_FLAG_BOTH);
370 info->nor->cmd_address1 = 0xAAB;
371 info->nor->cmd_address2 = 0x555;
372 info->map[1].start = 0xA130C0;
373 info->map[1].end = 0xA130D0;
374 info->map[1].mask = 0xFFFFFF;
375 if (!strcmp(
376 "on",
377 tern_find_path_default(config, "system\0megawifi\0", (tern_val){.ptrval="off"}, TVAL_PTR).ptrval)
378 ) {
379 info->map[1].write_16 = megawifi_write_w;
380 info->map[1].write_8 = megawifi_write_b;
381 info->map[1].read_16 = megawifi_read_w;
382 info->map[1].read_8 = megawifi_read_b;
383 } else {
384 warning("ROM uses MegaWiFi, but it is disabled\n");
385 }
298 return; 386 return;
299 } else if (has_ram_header(rom, size)) { 387 } else if (has_ram_header(rom, size)) {
300 uint32_t ram_start = read_ram_header(info, rom); 388 uint32_t ram_start = read_ram_header(info, rom);
301 389
302 if (info->save_buffer) { 390 if (info->save_buffer) {
322 410
323 if (info->save_type == RAM_FLAG_ODD) { 411 if (info->save_type == RAM_FLAG_ODD) {
324 info->map[1].flags |= MMAP_ONLY_ODD; 412 info->map[1].flags |= MMAP_ONLY_ODD;
325 } else if (info->save_type == RAM_FLAG_EVEN) { 413 } else if (info->save_type == RAM_FLAG_EVEN) {
326 info->map[1].flags |= MMAP_ONLY_EVEN; 414 info->map[1].flags |= MMAP_ONLY_EVEN;
415 } else {
416 info->map[1].flags |= MMAP_CODE;
327 } 417 }
328 info->map[1].buffer = info->save_buffer; 418 info->map[1].buffer = info->save_buffer;
329 } else { 419 } else {
330 //Assume the standard Sega mapper 420 //Assume the standard Sega mapper
331 info->mapper_type = MAPPER_SEGA; 421 info->mapper_type = MAPPER_SEGA_SRAM;
332 info->map[0].end = 0x200000; 422 info->map[0].end = 0x200000;
333 info->map[0].mask = 0xFFFFFF; 423 info->map[0].mask = 0xFFFFFF;
334 info->map[0].flags = MMAP_READ; 424 info->map[0].flags = MMAP_READ;
335 info->map[0].buffer = rom; 425 info->map[0].buffer = rom;
336 426
343 info->map[1].read_8 = (read_8_fun)read_sram_b; 433 info->map[1].read_8 = (read_8_fun)read_sram_b;
344 info->map[1].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area 434 info->map[1].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
345 info->map[1].write_8 = (write_8_fun)write_sram_area_b; 435 info->map[1].write_8 = (write_8_fun)write_sram_area_b;
346 info->map[1].buffer = rom + 0x200000; 436 info->map[1].buffer = rom + 0x200000;
347 437
438 //Last entry in the base map is a catch all one that needs to be
439 //after all the other entries
440 memmap_chunk *unused = info->map + info->map_chunks - 2;
348 memmap_chunk *last = info->map + info->map_chunks - 1; 441 memmap_chunk *last = info->map + info->map_chunks - 1;
442 *last = *unused;
443 last = unused;
349 memset(last, 0, sizeof(memmap_chunk)); 444 memset(last, 0, sizeof(memmap_chunk));
350 last->start = 0xA13000; 445 last->start = 0xA13000;
351 last->end = 0xA13100; 446 last->end = 0xA13100;
352 last->mask = 0xFF; 447 last->mask = 0xFF;
353 last->write_16 = (write_16_fun)write_bank_reg_w; 448 last->write_16 = (write_16_fun)write_bank_reg_w;
354 last->write_8 = (write_8_fun)write_bank_reg_b; 449 last->write_8 = (write_8_fun)write_bank_reg_b;
355 } 450 }
356 return; 451 return;
357 } 452 }
358 } 453 }
359 454
360 info->map_chunks = base_chunks + 1; 455 info->map_chunks = base_chunks + 1;
361 info->map = malloc(sizeof(memmap_chunk) * info->map_chunks); 456 info->map = malloc(sizeof(memmap_chunk) * info->map_chunks);
362 memset(info->map, 0, sizeof(memmap_chunk)); 457 memset(info->map, 0, sizeof(memmap_chunk));
363 memcpy(info->map+1, base_map, sizeof(memmap_chunk) * base_chunks); 458 memcpy(info->map+1, base_map, sizeof(memmap_chunk) * base_chunks);
364 459
450 state->info->save_size = atoi(size); 545 state->info->save_size = atoi(size);
451 if (!state->info->save_size) { 546 if (!state->info->save_size) {
452 fatal_error("SRAM size %s is invalid\n", size); 547 fatal_error("SRAM size %s is invalid\n", size);
453 } 548 }
454 state->info->save_mask = nearest_pow2(state->info->save_size)-1; 549 state->info->save_mask = nearest_pow2(state->info->save_size)-1;
455 state->info->save_buffer = malloc(state->info->save_size); 550 state->info->save_buffer = calloc(state->info->save_size, 1);
456 memset(state->info->save_buffer, 0, state->info->save_size);
457 char *bus = tern_find_path(state->root, "SRAM\0bus\0", TVAL_PTR).ptrval; 551 char *bus = tern_find_path(state->root, "SRAM\0bus\0", TVAL_PTR).ptrval;
458 if (!strcmp(bus, "odd")) { 552 if (!strcmp(bus, "odd")) {
459 state->info->save_type = RAM_FLAG_ODD; 553 state->info->save_type = RAM_FLAG_ODD;
460 } else if(!strcmp(bus, "even")) { 554 } else if(!strcmp(bus, "even")) {
461 state->info->save_type = RAM_FLAG_EVEN; 555 state->info->save_type = RAM_FLAG_EVEN;
528 state->info->save_buffer = malloc(state->info->save_size); 622 state->info->save_buffer = malloc(state->info->save_size);
529 char *init = tern_find_path_default(state->root, "NOR\0init\0", (tern_val){.ptrval="FF"}, TVAL_PTR).ptrval; 623 char *init = tern_find_path_default(state->root, "NOR\0init\0", (tern_val){.ptrval="FF"}, TVAL_PTR).ptrval;
530 if (!strcmp(init, "ROM")) { 624 if (!strcmp(init, "ROM")) {
531 uint32_t init_size = state->rom_size > state->info->save_size ? state->info->save_size : state->rom_size; 625 uint32_t init_size = state->rom_size > state->info->save_size ? state->info->save_size : state->rom_size;
532 memcpy(state->info->save_buffer, state->rom, init_size); 626 memcpy(state->info->save_buffer, state->rom, init_size);
627 if (init_size < state->info->save_size) {
628 memset(state->info->save_buffer + init_size, 0xFF, state->info->save_size - init_size);
629 }
533 if (state->info->save_bus == RAM_FLAG_BOTH) { 630 if (state->info->save_bus == RAM_FLAG_BOTH) {
534 byteswap_rom(state->info->save_size, (uint16_t *)state->info->save_buffer); 631 byteswap_rom(state->info->save_size, (uint16_t *)state->info->save_buffer);
535 } 632 }
536 } else { 633 } else {
537 memset(state->info->save_buffer, strtol(init, NULL, 16), state->info->save_size); 634 memset(state->info->save_buffer, strtol(init, NULL, 16), state->info->save_size);
561 } 658 }
562 tern_node * bits_write = tern_find_node(node, "bits_write"); 659 tern_node * bits_write = tern_find_node(node, "bits_write");
563 if (bits_write) { 660 if (bits_write) {
564 tern_foreach(bits_write, eeprom_write_fun, eep_map); 661 tern_foreach(bits_write, eeprom_write_fun, eep_map);
565 } 662 }
566 printf("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); 663 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);
567 state->info->num_eeprom++; 664 state->info->num_eeprom++;
568 } 665 }
569 666
570 void map_iter_fun(char *key, tern_val val, uint8_t valtype, void *data) 667 void map_iter_fun(char *key, tern_val val, uint8_t valtype, void *data)
571 { 668 {
626 continue; 723 continue;
627 } 724 }
628 *map = lock_info.map[i]; 725 *map = lock_info.map[i];
629 if (map->start < 0x200000) { 726 if (map->start < 0x200000) {
630 if (map->buffer) { 727 if (map->buffer) {
631 map->buffer += (0x200000 - map->start) & ((map->flags & MMAP_AUX_BUFF) ? map->aux_mask : map->mask); 728 uint8_t *buf = map->buffer;
729 buf += (0x200000 - map->start) & ((map->flags & MMAP_AUX_BUFF) ? map->aux_mask : map->mask);
730 map->buffer = buf;
632 } 731 }
633 map->start = 0x200000; 732 map->start = 0x200000;
634 } 733 }
635 map++; 734 map++;
636 state->index++; 735 state->index++;
666 map->flags = MMAP_READ | MMAP_WRITE; 765 map->flags = MMAP_READ | MMAP_WRITE;
667 if (state->info->save_type == RAM_FLAG_ODD) { 766 if (state->info->save_type == RAM_FLAG_ODD) {
668 map->flags |= MMAP_ONLY_ODD; 767 map->flags |= MMAP_ONLY_ODD;
669 } else if(state->info->save_type == RAM_FLAG_EVEN) { 768 } else if(state->info->save_type == RAM_FLAG_EVEN) {
670 map->flags |= MMAP_ONLY_EVEN; 769 map->flags |= MMAP_ONLY_EVEN;
770 } else {
771 map->flags |= MMAP_CODE;
671 } 772 }
672 map->mask = calc_mask(state->info->save_size, start, end); 773 map->mask = calc_mask(state->info->save_size, start, end);
673 } else if (!strcmp(dtype, "RAM")) { 774 } else if (!strcmp(dtype, "RAM")) {
674 uint32_t size = strtol(tern_find_ptr_default(node, "size", "0"), NULL, 16); 775 uint32_t size = strtol(tern_find_ptr_default(node, "size", "0"), NULL, 16);
675 if (!size || size > map->end - map->start) { 776 if (!size || size > map->end - map->start) {
676 size = map->end - map->start; 777 size = map->end - map->start;
677 } 778 }
678 map->buffer = malloc(size); 779 map->buffer = calloc(size, 1);
679 map->mask = calc_mask(size, start, end); 780 map->mask = calc_mask(size, start, end);
680 map->flags = MMAP_READ | MMAP_WRITE; 781 map->flags = MMAP_READ | MMAP_WRITE;
681 char *bus = tern_find_ptr_default(node, "bus", "both"); 782 char *bus = tern_find_ptr_default(node, "bus", "both");
682 if (!strcmp(bus, "odd")) { 783 if (!strcmp(bus, "odd")) {
683 map->flags |= MMAP_ONLY_ODD; 784 map->flags |= MMAP_ONLY_ODD;
686 } else { 787 } else {
687 map->flags |= MMAP_CODE; 788 map->flags |= MMAP_CODE;
688 } 789 }
689 } else if (!strcmp(dtype, "NOR")) { 790 } else if (!strcmp(dtype, "NOR")) {
690 process_nor_def(key, state); 791 process_nor_def(key, state);
691 792
692 map->write_16 = nor_flash_write_w; 793 map->write_16 = nor_flash_write_w;
693 map->write_8 = nor_flash_write_b; 794 map->write_8 = nor_flash_write_b;
694 map->read_16 = nor_flash_read_w; 795 map->read_16 = nor_flash_read_w;
695 map->read_8 = nor_flash_read_b; 796 map->read_8 = nor_flash_read_b;
696 if (state->info->save_bus == RAM_FLAG_BOTH) { 797 if (state->info->save_bus == RAM_FLAG_BOTH) {
772 map->start = 0xA13000; 873 map->start = 0xA13000;
773 map->end = 0xA13100; 874 map->end = 0xA13100;
774 map->mask = 0xFF; 875 map->mask = 0xFF;
775 map->write_16 = (write_16_fun)write_bank_reg_w; 876 map->write_16 = (write_16_fun)write_bank_reg_w;
776 map->write_8 = (write_8_fun)write_bank_reg_b; 877 map->write_8 = (write_8_fun)write_bank_reg_b;
878 #ifndef IS_LIB
777 } else if (!strcmp(dtype, "MENU")) { 879 } else if (!strcmp(dtype, "MENU")) {
778 //fake hardware for supporting menu 880 //fake hardware for supporting menu
779 map->buffer = NULL; 881 map->buffer = NULL;
780 map->mask = 0xFF; 882 map->mask = 0xFF;
781 map->write_16 = menu_write_w; 883 map->write_16 = menu_write_w;
782 map->read_16 = menu_read_w; 884 map->read_16 = menu_read_w;
885 #endif
783 } else if (!strcmp(dtype, "fixed")) { 886 } else if (!strcmp(dtype, "fixed")) {
784 uint16_t *value = malloc(2); 887 uint16_t *value = malloc(2);
785 map->buffer = value; 888 map->buffer = value;
786 map->mask = 0; 889 map->mask = 0;
787 map->flags = MMAP_READ; 890 map->flags = MMAP_READ;
809 map->mask = 0xFF; 912 map->mask = 0xFF;
810 map->write_16 = write_multi_game_w; 913 map->write_16 = write_multi_game_w;
811 map->write_8 = write_multi_game_b; 914 map->write_8 = write_multi_game_b;
812 } else if (!strcmp(dtype, "megawifi")) { 915 } else if (!strcmp(dtype, "megawifi")) {
813 if (!strcmp( 916 if (!strcmp(
814 "on", 917 "on",
815 tern_find_path_default(config, "system\0megawifi\0", (tern_val){.ptrval="off"}, TVAL_PTR).ptrval) 918 tern_find_path_default(config, "system\0megawifi\0", (tern_val){.ptrval="off"}, TVAL_PTR).ptrval)
816 ) { 919 ) {
817 map->write_16 = megawifi_write_w; 920 map->write_16 = megawifi_write_w;
818 map->write_8 = megawifi_write_b; 921 map->write_8 = megawifi_write_b;
819 map->read_16 = megawifi_read_w; 922 map->read_16 = megawifi_read_w;
848 break; 951 break;
849 } 952 }
850 product_id[i] = rom[GAME_ID_OFF + i]; 953 product_id[i] = rom[GAME_ID_OFF + i];
851 954
852 } 955 }
853 printf("Product ID: %s\n", product_id); 956 debug_message("Product ID: %s\n", product_id);
854 uint8_t raw_hash[20]; 957 uint8_t raw_hash[20];
855 sha1(vrom, rom_size, raw_hash); 958 sha1(vrom, rom_size, raw_hash);
856 uint8_t hex_hash[41]; 959 uint8_t hex_hash[41];
857 bin_to_hex(hex_hash, raw_hash, 20); 960 bin_to_hex(hex_hash, raw_hash, 20);
858 printf("SHA1: %s\n", hex_hash); 961 debug_message("SHA1: %s\n", hex_hash);
859 tern_node * entry = tern_find_node(rom_db, hex_hash); 962 tern_node * entry = tern_find_node(rom_db, hex_hash);
860 if (!entry) { 963 if (!entry) {
861 entry = tern_find_node(rom_db, product_id); 964 entry = tern_find_node(rom_db, product_id);
862 } 965 }
863 if (!entry) { 966 if (!entry) {
864 puts("Not found in ROM DB, examining header\n"); 967 debug_message("Not found in ROM DB, examining header\n\n");
865 if (xband_detect(rom, rom_size)) { 968 if (xband_detect(rom, rom_size)) {
866 return xband_configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, base_chunks); 969 return xband_configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, base_chunks);
867 } 970 }
868 if (realtec_detect(rom, rom_size)) { 971 if (realtec_detect(rom, rom_size)) {
869 return realtec_configure_rom(rom, rom_size, base_map, base_chunks); 972 return realtec_configure_rom(rom, rom_size, base_map, base_chunks);
872 } 975 }
873 rom_info info; 976 rom_info info;
874 info.mapper_type = MAPPER_NONE; 977 info.mapper_type = MAPPER_NONE;
875 info.name = tern_find_ptr(entry, "name"); 978 info.name = tern_find_ptr(entry, "name");
876 if (info.name) { 979 if (info.name) {
877 printf("Found name: %s\n", info.name); 980 debug_message("Found name: %s\n\n", info.name);
878 info.name = strdup(info.name); 981 info.name = strdup(info.name);
879 } else { 982 } else {
880 info.name = get_header_name(rom); 983 info.name = get_header_name(rom);
881 } 984 }
882 985
906 info.map = malloc(sizeof(memmap_chunk) * info.map_chunks); 1009 info.map = malloc(sizeof(memmap_chunk) * info.map_chunks);
907 info.eeprom_map = NULL; 1010 info.eeprom_map = NULL;
908 info.num_eeprom = 0; 1011 info.num_eeprom = 0;
909 memset(info.map, 0, sizeof(memmap_chunk) * info.map_chunks); 1012 memset(info.map, 0, sizeof(memmap_chunk) * info.map_chunks);
910 map_iter_state state = { 1013 map_iter_state state = {
911 .info = &info, 1014 .info = &info,
912 .rom = rom, 1015 .rom = rom,
913 .lock_on = lock_on, 1016 .lock_on = lock_on,
914 .root = entry, 1017 .root = entry,
915 .rom_db = rom_db, 1018 .rom_db = rom_db,
916 .rom_size = rom_size, 1019 .rom_size = rom_size,
917 .lock_on_size = lock_on_size, 1020 .lock_on_size = lock_on_size,
918 .index = 0, 1021 .index = 0,
919 .num_els = info.map_chunks - base_chunks, 1022 .num_els = info.map_chunks - base_chunks,
920 .ptr_index = 0 1023 .ptr_index = 0
921 }; 1024 };
922 tern_foreach(map, map_iter_fun, &state); 1025 tern_foreach(map, map_iter_fun, &state);
923 memcpy(info.map + state.index, base_map, sizeof(memmap_chunk) * base_chunks); 1026 memcpy(info.map + state.index, base_map, sizeof(memmap_chunk) * base_chunks);
933 tern_node *device_overrides = tern_find_node(entry, "device_overrides"); 1036 tern_node *device_overrides = tern_find_node(entry, "device_overrides");
934 if (device_overrides) { 1037 if (device_overrides) {
935 info.port1_override = tern_find_ptr(device_overrides, "1"); 1038 info.port1_override = tern_find_ptr(device_overrides, "1");
936 info.port2_override = tern_find_ptr(device_overrides, "2"); 1039 info.port2_override = tern_find_ptr(device_overrides, "2");
937 info.ext_override = tern_find_ptr(device_overrides, "ext"); 1040 info.ext_override = tern_find_ptr(device_overrides, "ext");
1041 if (
1042 info.save_type == SAVE_NONE
1043 && (
1044 (info.port1_override && startswith(info.port1_override, "heartbeat_trainer."))
1045 || (info.port2_override && startswith(info.port2_override, "heartbeat_trainer."))
1046 || (info.ext_override && startswith(info.ext_override, "heartbeat_trainer."))
1047 )
1048 ) {
1049 info.save_type = SAVE_HBPT;
1050 info.save_size = atoi(tern_find_path_default(entry, "HeartbeatTrainer\0size\0", (tern_val){.ptrval="512"}, TVAL_PTR).ptrval);
1051 info.save_buffer = calloc(info.save_size + 5 + 8, 1);
1052 memset(info.save_buffer, 0xFF, info.save_size);
1053 }
938 } else { 1054 } else {
939 info.port1_override = info.port2_override = info.ext_override = NULL; 1055 info.port1_override = info.port2_override = info.ext_override = NULL;
940 } 1056 }
941 info.mouse_mode = tern_find_ptr(entry, "mouse_mode"); 1057 info.mouse_mode = tern_find_ptr(entry, "mouse_mode");
942 1058