/** *\brief will compare 22V10 GAL jedec files for functional equivalence * *return value: *1: _probably_ differs. *0: surely identical. *3: some error(different parts, file missing...) */ int main (int argc, char *argv[]) { jed_ctx a_jed, b_jed; int rv = 0; if (argc < 3) { fprintf (stderr, "Error: Need two arguments.\n"); fprintf (stderr, usage); return 1; } jed_ctx_init (&a_jed); jed_ctx_init (&b_jed); if (jed_parse (argv[1], &a_jed)) return 3; if (jed_parse (argv[2], &b_jed)) { jed_ctx_clear (&a_jed); return 3; } rv = jed_cmp (&a_jed, &b_jed); jed_ctx_clear (&a_jed); jed_ctx_clear (&b_jed); if (rv == 1) fprintf (stderr, "%s and %s probably differ.\n", argv[1], argv[2]); if (rv == 0) fprintf (stderr, "%s and %s are identical.\n", argv[1], argv[2]); return rv; }
void media_identifier::digest_data(std::vector<file_info> &info, char const *name, void const *data, std::uint64_t length) { util::hash_collection hashes; // if this is a '.jed' file, process it into raw bits first if (core_filename_ends_with(name, ".jed")) { jed_data jed; if (JEDERR_NONE == jed_parse(data, length, &jed)) { try { // now determine the new data length and allocate temporary memory for it std::vector<uint8_t> tempjed(jedbin_output(&jed, nullptr, 0)); jedbin_output(&jed, &tempjed[0], tempjed.size()); hashes.compute(&tempjed[0], tempjed.size(), util::hash_collection::HASH_TYPES_CRC_SHA1); info.emplace_back(name, tempjed.size(), std::move(hashes), file_flavour::JED); m_total++; return; } catch (...) { } } } hashes.compute(reinterpret_cast<std::uint8_t const *>(data), length, util::hash_collection::HASH_TYPES_CRC_SHA1); info.emplace_back(name, length, std::move(hashes), file_flavour::RAW); m_total++; }
static void identify_data(const char *name, const UINT8 *data, int length, romident_status *status) { char hash[HASH_BUF_SIZE]; UINT8 *tempjed = NULL; astring *basename; int found = 0; jed_data jed; /* if this is a '.jed' file, process it into raw bits first */ if (core_filename_ends_with(name, ".jed") && jed_parse(data, length, &jed) == JEDERR_NONE) { /* now determine the new data length and allocate temporary memory for it */ length = jedbin_output(&jed, NULL, 0); tempjed = malloc(length); if (tempjed == NULL) return; /* create a binary output of the JED data and use that instead */ jedbin_output(&jed, tempjed, length); data = tempjed; } /* compute the hash of the data */ hash_data_clear(hash); hash_compute(hash, data, length, HASH_SHA1 | HASH_CRC); /* output the name */ status->total++; basename = core_filename_extract_base(astring_alloc(), name, FALSE); mame_printf_info("%-20s", astring_c(basename)); astring_free(basename); /* see if we can find a match in the ROMs */ match_roms(hash, length, &found); /* if we didn't find it, try to guess what it might be */ if (found == 0) { /* if not a power of 2, assume it is a non-ROM file */ if ((length & (length - 1)) != 0) { mame_printf_info("NOT A ROM\n"); status->nonroms++; } /* otherwise, it's just not a match */ else mame_printf_info("NO MATCH\n"); } /* if we did find it, count it as a match */ else status->matches++; /* free any temporary JED data */ if (tempjed != NULL) free(tempjed); }
int main(int argc, char *argv[]) { const char *srcfile, *dstfile; int src_is_jed, dst_is_jed; int numfuses = 0; jed_data jed; int len; int err; /* needs at least two arguments */ if (argc < 3) { fprintf(stderr, "Usage:\n" " jedutil <source.jed> <target.bin> [fuses] -- convert JED to binary form\n" " jedutil <source.bin> <target.jed> -- convert binary to JED form\n" ); return 0; } /* extract arguments */ srcfile = argv[1]; dstfile = argv[2]; if (argc >= 4) numfuses = atoi(argv[3]); /* does the source end in '.jed'? */ len = strlen(srcfile); src_is_jed = (srcfile[len - 4] == '.' && tolower(srcfile[len - 3]) == 'j' && tolower(srcfile[len - 2]) == 'e' && tolower(srcfile[len - 1]) == 'd'); /* does the destination end in '.jed'? */ len = strlen(dstfile); dst_is_jed = (dstfile[len - 4] == '.' && tolower(dstfile[len - 3]) == 'j' && tolower(dstfile[len - 2]) == 'e' && tolower(dstfile[len - 1]) == 'd'); /* error if neither or both are .jed */ if (!src_is_jed && !dst_is_jed) { fprintf(stderr, "At least one of the filenames must end in .jed!\n"); return 1; } if (src_is_jed && dst_is_jed) { fprintf(stderr, "Both filenames cannot end in .jed!\n"); return 1; } /* read the source file */ err = read_source_file(srcfile); if (err != 0) return 1; /* if the source is JED, convert to binary */ if (src_is_jed) { printf("Converting '%s' to binary form '%s'\n", srcfile, dstfile); /* read the JEDEC data */ err = jed_parse(srcbuf, srcbuflen, &jed); switch (err) { case JEDERR_INVALID_DATA: fprintf(stderr, "Fatal error: Invalid .JED file\n"); return 1; case JEDERR_BAD_XMIT_SUM: fprintf(stderr, "Fatal error: Bad transmission checksum\n"); return 1; case JEDERR_BAD_FUSE_SUM: fprintf(stderr, "Fatal error: Bad fusemap checksum\n"); return 1; } /* override the number of fuses */ if (numfuses != 0) jed.numfuses = numfuses; /* print out data */ printf("Source file read successfully\n"); printf(" Total fuses = %d\n", jed.numfuses); /* generate the output */ dstbuflen = jedbin_output(&jed, NULL, 0); dstbuf = malloc(dstbuflen); if (!dstbuf) { fprintf(stderr, "Unable to allocate %d bytes for the target buffer!\n", (int)dstbuflen); return 1; } dstbuflen = jedbin_output(&jed, dstbuf, dstbuflen); } /* if the source is binary, convert to JED */ else { printf("Converting '%s' to JED form '%s'\n", srcfile, dstfile); /* read the binary data */ err = jedbin_parse(srcbuf, srcbuflen, &jed); switch (err) { case JEDERR_INVALID_DATA: fprintf(stderr, "Fatal error: Invalid binary JEDEC file\n"); return 1; } /* print out data */ printf("Source file read successfully\n"); printf(" Total fuses = %d\n", jed.numfuses); /* generate the output */ dstbuflen = jed_output(&jed, NULL, 0); dstbuf = malloc(dstbuflen); if (!dstbuf) { fprintf(stderr, "Unable to allocate %d bytes for the target buffer!\n", (int)dstbuflen); return 1; } dstbuflen = jed_output(&jed, dstbuf, dstbuflen); } /* write the destination file */ err = write_dest_file(dstfile); if (err != 0) return 1; printf("Target file written succesfully\n"); return 0; }
void media_identifier::digest_file(std::vector<file_info> &info, char const *path) { // CHD files need to be parsed and their hashes extracted from the header if (core_filename_ends_with(path, ".chd")) { // attempt to open as a CHD; fail if not chd_file chd; chd_error const err = chd.open(path); m_total++; if (err != CHDERR_NONE) { osd_printf_info("%-20sNOT A CHD\n", core_filename_extract_base(path).c_str()); m_nonroms++; } else if (!chd.compressed()) { osd_printf_info("%-20sis a writeable CHD\n", core_filename_extract_base(path).c_str()); } else { // otherwise, get the hash collection for this CHD util::hash_collection hashes; if (chd.sha1() != util::sha1_t::null) hashes.add_sha1(chd.sha1()); info.emplace_back(path, chd.logical_bytes(), std::move(hashes), file_flavour::CHD); } } else { // if this is a '.jed' file, process it into raw bits first if (core_filename_ends_with(path, ".jed")) { // load the file and process if it opens and has a valid length uint32_t length; void *data; if (osd_file::error::NONE == util::core_file::load(path, &data, length)) { jed_data jed; if (JEDERR_NONE == jed_parse(data, length, &jed)) { try { // now determine the new data length and allocate temporary memory for it std::vector<uint8_t> tempjed(jedbin_output(&jed, nullptr, 0)); jedbin_output(&jed, &tempjed[0], tempjed.size()); util::hash_collection hashes; hashes.compute(&tempjed[0], tempjed.size(), util::hash_collection::HASH_TYPES_CRC_SHA1); info.emplace_back(path, tempjed.size(), std::move(hashes), file_flavour::JED); free(data); m_total++; return; } catch (...) { } } free(data); } } // load the file and process if it opens and has a valid length util::core_file::ptr file; if ((osd_file::error::NONE == util::core_file::open(path, OPEN_FLAG_READ, file)) && file) { util::hash_collection hashes; hashes.begin(util::hash_collection::HASH_TYPES_CRC_SHA1); std::uint8_t buf[1024]; for (std::uint64_t remaining = file->size(); remaining; ) { std::uint32_t const block = std::min<std::uint64_t>(remaining, sizeof(buf)); if (file->read(buf, block) < block) { osd_printf_error("%s: error reading file\n", path); return; } remaining -= block; hashes.buffer(buf, block); } hashes.end(); info.emplace_back(path, file->size(), std::move(hashes), file_flavour::RAW); m_total++; } else { osd_printf_error("%s: error opening file\n", path); } } }