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