/*************************************************************************** jedutil.c JEDEC file utilities. Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team. Visit http://mamedev.org for licensing and usage restrictions. **************************************************************************** Binary file format: Offset 0 = Total number of fuses (32 bits) 4 = Raw fuse data, packed 8 bits at a time, LSB to MSB **************************************************************************** Known types: 20-pin devices: PAL10H8 = QP20 QF0320 PAL12H6 = QP20 QF0320 PAL14H4 = QP20 PAL16H2 = QP20 PAL16C1 = QP20 PAL10L8 = QP20 QF0320 PAL12L6 = QP20 PAL14L4 = QP20 PAL16L2 = QP20 15S8 = QP20 QF0448 PLS153 = QP20 QF1842 PAL16L8 = QP20 QF2048 PAL16RA8 = QP20 QF2056 PAL16V8R = QP20 QF2194 PALCE16V8 = QP20 QF2194 GAL16V8A = QP20 QF2194 18CV8 = QP20 QF2696 24-pin devices: GAL20V8A = QP24 QF2706 GAL22V10 = QP24 QF5892 28-pin devices: PLS100 = QP28 QF1928 ***************************************************************************/ #include #include #include #include #include "jedparse.h" /*************************************************************************** GLOBAL VARIABLES ***************************************************************************/ static UINT8 *srcbuf; static size_t srcbuflen; static UINT8 *dstbuf; static size_t dstbuflen; /*************************************************************************** CORE IMPLEMENTATION ***************************************************************************/ /*------------------------------------------------- read_source_file - read a raw source file into an allocated memory buffer -------------------------------------------------*/ static int read_source_file(const char *srcfile) { size_t bytes; FILE *file; /* open the source file */ file = fopen(srcfile, "rb"); if (!file) { fprintf(stderr, "Unable to open source file '%s'!\n", srcfile); return 1; } /* allocate memory for the data */ fseek(file, 0, SEEK_END); srcbuflen = ftell(file); fseek(file, 0, SEEK_SET); srcbuf = malloc(srcbuflen); if (!srcbuf) { fprintf(stderr, "Unable to allocate %d bytes for the source!\n", (int)srcbuflen); fclose(file); return 1; } /* read the data */ bytes = fread(srcbuf, 1, srcbuflen, file); if (bytes != srcbuflen) { fprintf(stderr, "Error reading %d bytes from the source!\n", (int)srcbuflen); free(srcbuf); fclose(file); return 1; } /* close up shop */ fclose(file); return 0; } /*------------------------------------------------- write_dest_file - write a memory buffer raw into a desintation file -------------------------------------------------*/ static int write_dest_file(const char *dstfile) { size_t bytes; FILE *file; /* open the source file */ file = fopen(dstfile, "wb"); if (!file) { fprintf(stderr, "Unable to open target file '%s'!\n", dstfile); return 1; } /* write the data */ bytes = fwrite(dstbuf, 1, dstbuflen, file); if (bytes != dstbuflen) { fprintf(stderr, "Error writing %d bytes to the target!\n", (int)dstbuflen); fclose(file); return 1; } /* close up shop */ fclose(file); return 0; } /*------------------------------------------------- main - primary entry point -------------------------------------------------*/ 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 [fuses] -- convert JED to binary form\n" " jedutil -- 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; }