diff --git a/src/devices/machine/pla.cpp b/src/devices/machine/pla.cpp index 44db6a4ed10..463ccc334cc 100644 --- a/src/devices/machine/pla.cpp +++ b/src/devices/machine/pla.cpp @@ -12,9 +12,11 @@ #include "plaparse.h" #define LOG_TERMS (1 << 0U) -//#define VERBOSE (LOG_TERMS) -#include "logmacro.h" +//#define VERBOSE (LOG_TERMS) +//#define LOG_OUTPUT_STREAM std::cout + +#include "logmacro.h" DEFINE_DEVICE_TYPE(PLA, pla_device, "pla", "PLA") DEFINE_DEVICE_TYPE(PLS100, pls100_device, "pls100", "82S100-series PLA") @@ -123,6 +125,8 @@ void pla_device::parse_fusemap() return; } + LOGMASKED(LOG_TERMS, "PLA read and parsed, %d fuses in %s format\n", jed.numfuses, jed.binfmt == MAXLOADER ? "Maxloader" : "DataIO" ); + // parse it uint32_t fusenum = 0; @@ -135,11 +139,21 @@ void pla_device::parse_fusemap() for (int i = 0; i < m_inputs; i++) { - // complement - term->and_mask |= (uint64_t)jed_get_fuse(&jed, fusenum++) << (i + 32); - - // true - term->and_mask |= (uint64_t)jed_get_fuse(&jed, fusenum++) << i; + if (jed.binfmt == MAXLOADER) + { + term->and_mask |= (uint64_t)jed_get_fuse(&jed, fusenum++) << (i + 32); // complement + term->and_mask |= (uint64_t)jed_get_fuse(&jed, fusenum++) << i; // true + } + else if (jed.binfmt == DATAIO) + { + term->and_mask |= (uint64_t)jed_get_fuse(&jed, fusenum++) << i; // true + term->and_mask |= (uint64_t)jed_get_fuse(&jed, fusenum++) << (i + 32); // complement + } + else + { + logerror("PLA parser: Unknown JED format\n"); + break; + } } // OR mask diff --git a/src/lib/util/jedparse.cpp b/src/lib/util/jedparse.cpp index c2c9a139a6a..f7b252861a2 100644 --- a/src/lib/util/jedparse.cpp +++ b/src/lib/util/jedparse.cpp @@ -391,9 +391,24 @@ int jedbin_parse(const void *data, size_t length, jed_data *result) /* first unpack the number of fuses */ result->numfuses = (cursrc[0] << 24) | (cursrc[1] << 16) | (cursrc[2] << 8) | cursrc[3]; cursrc += 4; + if (result->numfuses == 0 || result->numfuses > JED_MAX_FUSES) return JEDERR_INVALID_DATA; + /* Detect DataIO binary format and prepare for conversion. This transformation is based on observation of an 82S100 dump */ + if (result->numfuses == ((cursrc[0] << 24) | (cursrc[1] << 16) | (cursrc[2] << 8) | cursrc[3])) + { + result->numfuses = (result->numfuses - 9) * 8; // Double 32 bit byte file size header + trailing byte to Single 32 byte fuse count + cursrc = cursrc + 4; // Adjust start of buffer, trailing byte will not be copied below + result->binfmt = DATAIO; // DataIO also has swapped inverted/non-inverted line fuses so remember origin + if (LOG_PARSE) printf("DATAIO format detected\n"); + } + else + { + result->binfmt = MAXLOADER; // This is the old format just set for completeness. + if (LOG_PARSE) printf("MAXLOADER format detected\n"); + } + /* now make sure we have enough data in the source */ if (length < 4 + (result->numfuses + 7) / 8) return JEDERR_INVALID_DATA; diff --git a/src/lib/util/jedparse.h b/src/lib/util/jedparse.h index f12101ca154..6f120abbc8a 100644 --- a/src/lib/util/jedparse.h +++ b/src/lib/util/jedparse.h @@ -29,7 +29,10 @@ #define JEDERR_BAD_XMIT_SUM 2 #define JEDERR_BAD_FUSE_SUM 3 - +enum fileformats { + MAXLOADER, + DATAIO +}; /*************************************************************************** TYPE DEFINITIONS @@ -39,6 +42,7 @@ struct jed_data { uint32_t numfuses; /* number of defined fuses */ uint8_t fusemap[JED_MAX_FUSES / 8];/* array of bit-packed data */ + fileformats binfmt; /* file format MAXLOADER or DATAIO */ }; diff --git a/src/tools/jedutil.cpp b/src/tools/jedutil.cpp index d1c49ec7a79..8fcc650c1d7 100644 --- a/src/tools/jedutil.cpp +++ b/src/tools/jedutil.cpp @@ -7429,9 +7429,19 @@ static int command_convert(int argc, char *argv[]) /* read the binary data */ err = jedbin_parse(srcbuf, srcbuflen, &jed); - switch (err) + + if (err == JEDERR_INVALID_DATA) { - case JEDERR_INVALID_DATA: fprintf(stderr, "Fatal error: Invalid binary JEDEC file\n"); free(srcbuf); return 1; + fprintf(stderr, "Fatal error: Invalid binary JEDEC file\n"); + free(srcbuf); + return 1; + } + + if (jed.binfmt == DATAIO) // DATAIO is detected and not supported yet, it has swapped inverted/non-inverted line fuses + { + fprintf(stderr, "Fatal error: Unsupported DATAIO PLA format detected\n"); + free(srcbuf); + return 1; } /* print out data */