int split_rom_load(struct emu *emu, const char *filename, struct rom **romptr) { struct archive *archive; uint8_t *buffer; size_t size; struct rom_info *rom_info; struct rom *rom; int *chip_list; int i; if (!romptr) return -1; chip_list = NULL; *romptr = NULL; if (archive_open(&archive, filename)) return -1; chip_list = malloc(archive->file_list->count * sizeof(*chip_list)); if (!chip_list) return -1; rom_info = NULL; rom = NULL; buffer = NULL; do { rom_info = db_lookup_split_rom(archive, chip_list, rom_info); if (!rom_info) break; if (load_split_rom_parts(archive, chip_list, rom_info, &buffer, &size)) { break; } if (!buffer) continue; rom = rom_alloc(filename, buffer, size); if (!rom) break; /* Store the filename of the first PRG chip as the empty string; this allows patches to be included with split roms as well, but they need to be located in the top-level directory of the archive. */ rom->compressed_filename = strdup(""); buffer = NULL; memcpy(&rom->info, rom_info, sizeof(*rom_info)); if (rom_info->name) rom->info.name = strdup(rom_info->name); else rom->info.name = NULL; rom->offset = INES_HEADER_SIZE; rom_calculate_checksum(rom); for (i = 0; i < archive->file_list->count; i++) { char *basename; if (!archive->file_list->entries[i].name) continue; basename = strrchr(archive->file_list->entries[i].name, '/'); if (!basename) basename = archive->file_list->entries[i].name; /* Hack for PlayChoice ROMs; most of these are the same as NES carts, so check for a file called 'security.prm' to distinguish them. */ if (!strcasecmp(basename, "security.prm")) { if (rom->info.flags & ROM_FLAG_PLAYCHOICE) rom->info.system_type = EMU_SYSTEM_TYPE_PLAYCHOICE; } } /* Validate individual chip CRCs or SHA1s if present, then the combined CRC and/or SHA1, if present. */ if (!validate_checksums(rom, rom_info)) goto invalid; if ((rom->info.flags & ROM_FLAG_HAS_CRC) && (rom->info.combined_crc != rom_info->combined_crc)) { goto invalid; } if ((rom->info.flags & ROM_FLAG_HAS_SHA1) && memcmp(rom->info.combined_sha1, rom_info->combined_sha1, 20)) { goto invalid; } break; invalid: rom_free(rom); rom = NULL; } while (rom_info); archive_close(&archive); if (chip_list) free(chip_list); if (buffer) free(buffer); if (!rom) return -1; *romptr = rom; return 0; }
void emu_free(){ hal_free(); rom_free(); // mem_free(); }
/* Load a ROM image into memory */ rominfo_t *rom_load(const char *filename) { FILE *fp = fopen(filename, "rb"); if(fp == NULL) { log_printf("Can't open ROM file: %s\n", filename); return NULL; } fseek(fp, 0, SEEK_END); long sz = ftell( fp ); uint8_t *rom = (uint8_t *)malloc(sz); fseek(fp, 0, SEEK_SET); if(fread(rom, 1, sz, fp) != sz) { free(rom); fclose(fp); log_printf("Read error ROM file: %s (%ld)\n", filename, sz); return NULL; } fclose(fp); // printf("LOAD ROM: %s (%d)\n", filename, sz); rominfo_t *rominfo; rominfo = malloc(sizeof(rominfo_t)); if(NULL == rominfo) { return NULL; } memset(rominfo, 0, sizeof(rominfo_t)); strncpy(rominfo->filename, filename, PATH_MAX); /* Get the header and stick it into rominfo struct */ const uint8_t *bin = rom; { bin = rom_getheader(bin, rominfo); if(bin == NULL) { goto _fail; } } /* Make sure we really support the mapper */ if(false == mmc_peek(rominfo->mapper_number)) { log_printf("Mapper %d not yet implemented", rominfo->mapper_number); goto _fail; } /* iNES format doesn't tell us if we need SRAM, so ** we have to always allocate it -- bleh! ** UNIF, TAKE ME AWAY! AAAAAAAAAA!!! */ if(rom_allocsram(rominfo)) { goto _fail; } bin = rom_loadtrainer(bin, rominfo); { int ret = rom_loadrom(bin, rominfo); if (ret != 0) { goto _fail; } } rom_loadsram(rominfo); /* See if there's a palette we can load up */ rom_checkforpal(rominfo); log_printf("ROM loaded: %s", rom_getinfo(rominfo)); free(rom); return rominfo; _fail: free(rom); rom_free(rominfo); return NULL; }