Mercurial > repos > blastem
diff romdb.c @ 2052:3748a2a8a4b7
Support Sega mapper without 'SEGA SSF' in header or ROM DB entry and implement a subset of the extended Sega mapper implemented in the Mega Everdrive when 'SEGA SSF' is present
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 01 Jan 2022 18:54:46 -0800 |
parents | 8b2ef428d1aa |
children | 3414a4423de1 |
line wrap: on
line diff
--- a/romdb.c Fri Dec 31 13:03:21 2021 -0800 +++ b/romdb.c Sat Jan 01 18:54:46 2022 -0800 @@ -80,6 +80,7 @@ { case MAPPER_SEGA: case MAPPER_SEGA_SRAM: + case MAPPER_SEGA_MED_V2: sega_mapper_serialize(gen, buf); break; case MAPPER_REALTEC: @@ -126,7 +127,7 @@ //TODO: Should probably prefer the title field that corresponds to the user's region preference uint8_t *last = rom + TITLE_END - 1; uint8_t *src = rom + TITLE_START; - + for (;;) { while (last > src && (*last <= 0x20 || *last >= 0x80)) @@ -169,7 +170,7 @@ uint8_t region_bits[] = {REGION_J, REGION_U, REGION_E, REGION_J|REGION_U|REGION_E}; uint8_t translate_region_char(uint8_t c) -{ +{ for (int i = 0; i < sizeof(region_bits); i++) { if (c == region_chars[i]) { @@ -226,7 +227,7 @@ uint8_t has_ram_header(uint8_t *rom, uint32_t rom_size) { - return rom_size >= (RAM_END + 4) && rom[RAM_ID] == 'R' && rom[RAM_ID + 1] == 'A'; + return rom_size >= (RAM_END + 4) && rom[RAM_ID] == 'R' && rom[RAM_ID + 1] == 'A'; } uint32_t read_ram_header(rom_info *info, uint8_t *rom) @@ -253,44 +254,86 @@ void add_memmap_header(rom_info *info, uint8_t *rom, uint32_t size, memmap_chunk const *base_map, int base_chunks) { uint32_t rom_end = get_u32be(rom + ROM_END) + 1; + uint32_t rom_end_raw = rom_end; if (size > rom_end) { rom_end = size; } else if (rom_end > nearest_pow2(size)) { rom_end = nearest_pow2(size); } info->save_type = SAVE_NONE; - if (size >= 0x80000 && !memcmp("SEGA SSF", rom + 0x100, 8)) { + uint8_t is_med_ssf = size >= 0x108 && !memcmp("SEGA SSF", rom + 0x100, 8); + if (is_med_ssf || (size >= 0x400000 && rom_end_raw <= 0x400000)) { + if (is_med_ssf && rom_end < 16*1024*1024) { + info->rom = rom = realloc(rom, 16*1024*1024); + } info->mapper_start_index = 0; - info->mapper_type = MAPPER_SEGA; + info->mapper_type = is_med_ssf ? MAPPER_SEGA_MED_V2 : MAPPER_SEGA; info->map_chunks = base_chunks + 9; info->map = malloc(sizeof(memmap_chunk) * info->map_chunks); memset(info->map, 0, sizeof(memmap_chunk)*9); memcpy(info->map+9, base_map, sizeof(memmap_chunk) * base_chunks); - - info->map[0].start = 0; - info->map[0].end = 0x80000; - info->map[0].mask = 0xFFFFFF; - info->map[0].flags = MMAP_READ; - info->map[0].buffer = rom; - - if (has_ram_header(rom, size)){ - read_ram_header(info, rom); + + int i; + uint16_t map_flags; + if (is_med_ssf) { + i = 0; + map_flags = info->map[i].flags = MMAP_READ | MMAP_PTR_IDX | MMAP_CODE; + info->save_type = RAM_FLAG_BOTH; + info->save_size = 256*1024; + info->save_mask = info->save_size - 1; + info->save_buffer = rom + 16*1024*1024 - 256*1024; + } else { + i = 1; + map_flags = info->map[i].flags = MMAP_READ | MMAP_PTR_IDX | MMAP_CODE | MMAP_FUNC_NULL; + info->map[0].start = 0; + info->map[0].end = 0x80000; + info->map[0].mask = 0xFFFFFF; + info->map[0].flags = MMAP_READ; + info->map[0].buffer = rom; + + if (has_ram_header(rom, size)){ + read_ram_header(info, rom); + } } - - for (int i = 1; i < 8; i++) + static const write_8_fun med_w8[] = { + write_med_ram0_b, + write_med_ram1_b, + write_med_ram2_b, + write_med_ram3_b, + write_med_ram4_b, + write_med_ram5_b, + write_med_ram6_b, + write_med_ram7_b, + }; + static const write_16_fun med_w16[] = { + write_med_ram0_w, + write_med_ram1_w, + write_med_ram2_w, + write_med_ram3_w, + write_med_ram4_w, + write_med_ram5_w, + write_med_ram6_w, + write_med_ram7_w, + }; + + for (; i < 8; i++) { info->map[i].start = i * 0x80000; info->map[i].end = (i + 1) * 0x80000; info->map[i].mask = 0x7FFFF; info->map[i].buffer = (i + 1) * 0x80000 <= size ? rom + i * 0x80000 : rom; info->map[i].ptr_index = i; - info->map[i].flags = MMAP_READ | MMAP_PTR_IDX | MMAP_CODE | MMAP_FUNC_NULL; - - info->map[i].read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[i] == NULL - info->map[i].read_8 = (read_8_fun)read_sram_b; - info->map[i].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area - info->map[i].write_8 = (write_8_fun)write_sram_area_b; - + info->map[i].flags = map_flags; + + 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 + info->map[i].read_8 = is_med_ssf ? NULL : (read_8_fun)read_sram_b; + if (is_med_ssf) { + info->map[i].write_16 = med_w16[i]; + info->map[i].write_8 = med_w8[i]; + } else { + info->map[i].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area + info->map[i].write_8 = (write_8_fun)write_sram_area_b; + } } info->map[8].start = 0xA13000; info->map[8].end = 0xA13100; @@ -327,7 +370,7 @@ info->map[1].end = 0xA130D0; info->map[1].mask = 0xFFFFFF; if (!strcmp( - "on", + "on", tern_find_path_default(config, "system\0megawifi\0", (tern_val){.ptrval="off"}, TVAL_PTR).ptrval) ) { info->map[1].write_16 = megawifi_write_w; @@ -388,7 +431,7 @@ info->map[1].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area info->map[1].write_8 = (write_8_fun)write_sram_area_b; info->map[1].buffer = rom + 0x200000; - + //Last entry in the base map is a catch all one that needs to be //after all the other entries memmap_chunk *unused = info->map + info->map_chunks - 2; @@ -405,7 +448,7 @@ return; } } - + info->map_chunks = base_chunks + 1; info->map = malloc(sizeof(memmap_chunk) * info->map_chunks); memset(info->map, 0, sizeof(memmap_chunk)); @@ -743,7 +786,7 @@ } } else if (!strcmp(dtype, "NOR")) { process_nor_def(key, state); - + map->write_16 = nor_flash_write_w; map->write_8 = nor_flash_write_b; map->read_16 = nor_flash_read_w; @@ -868,7 +911,7 @@ map->write_8 = write_multi_game_b; } else if (!strcmp(dtype, "megawifi")) { if (!strcmp( - "on", + "on", tern_find_path_default(config, "system\0megawifi\0", (tern_val){.ptrval="off"}, TVAL_PTR).ptrval) ) { map->write_16 = megawifi_write_w; @@ -965,14 +1008,14 @@ info.num_eeprom = 0; memset(info.map, 0, sizeof(memmap_chunk) * info.map_chunks); map_iter_state state = { - .info = &info, - .rom = rom, + .info = &info, + .rom = rom, .lock_on = lock_on, .root = entry, .rom_db = rom_db, - .rom_size = rom_size, + .rom_size = rom_size, .lock_on_size = lock_on_size, - .index = 0, + .index = 0, .num_els = info.map_chunks - base_chunks, .ptr_index = 0 };