From 51992a75ecc31f2bff7c903f7d22db9e629c6230 Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Wed, 1 Feb 2017 18:29:57 +0000 Subject: [PATCH] apd_dsk: improved identify and simplified load (nw) --- src/lib/formats/apd_dsk.cpp | 121 +++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 50 deletions(-) diff --git a/src/lib/formats/apd_dsk.cpp b/src/lib/formats/apd_dsk.cpp index cd5de8ad206..3c972c25e49 100644 --- a/src/lib/formats/apd_dsk.cpp +++ b/src/lib/formats/apd_dsk.cpp @@ -11,7 +11,7 @@ #include #include "formats/apd_dsk.h" -static const uint8_t APD_HEADER[8] = { 0x41, 0x50, 0x44, 0x58, 0x30, 0x30, 0x30, 0x31 }; +static const uint8_t APD_HEADER[8] = { 'A', 'P', 'D', 'X', '0', '0', '0', '1' }; static const uint8_t GZ_HEADER[2] = { 0x1f, 0x8b }; apd_format::apd_format() @@ -35,10 +35,36 @@ const char *apd_format::extensions() const int apd_format::identify(io_generic *io, uint32_t form_factor) { - char h[8]; + uint64_t size = io_generic_size(io); + std::vector img(size); + io_generic_read(io, &img[0], 0, size); - io_generic_read(io, h, 0, 8); - if (!memcmp(h, GZ_HEADER, sizeof(GZ_HEADER)) || !memcmp(h, APD_HEADER, sizeof(APD_HEADER))) { + int err; + std::vector gz_ptr(8); + z_stream d_stream; + + if (!memcmp(&img[0], GZ_HEADER, sizeof(GZ_HEADER))) { + d_stream.zalloc = nullptr; + d_stream.zfree = nullptr; + d_stream.opaque = nullptr; + d_stream.next_in = &img[0]; + d_stream.avail_in = size; + d_stream.next_out = &gz_ptr[0]; + d_stream.avail_out = 8; + + err = inflateInit2(&d_stream, MAX_WBITS | 16); + if (err != Z_OK) return 0; + + err = inflate(&d_stream, Z_SYNC_FLUSH); + if (err != Z_OK) return 0; + + err = inflateEnd(&d_stream); + if (err != Z_OK) return 0; + + img = gz_ptr; + } + + if (!memcmp(&img[0], APD_HEADER, sizeof(APD_HEADER))) { return 100; } @@ -57,58 +83,53 @@ bool apd_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) int inflate_size = (img[size - 1] << 24) | (img[size - 2] << 16) | (img[size - 3] << 8) | img[size - 4]; uint8_t *in_ptr = &img[0]; - gz_ptr.resize(inflate_size); + if (!memcmp(&img[0], GZ_HEADER, sizeof(GZ_HEADER))) { + gz_ptr.resize(inflate_size); - d_stream.zalloc = nullptr; - d_stream.zfree = nullptr; - d_stream.opaque = nullptr; - d_stream.next_in = in_ptr; - d_stream.avail_in = size; - d_stream.next_out = &gz_ptr[0]; - d_stream.avail_out = inflate_size; + d_stream.zalloc = nullptr; + d_stream.zfree = nullptr; + d_stream.opaque = nullptr; + d_stream.next_in = in_ptr; + d_stream.avail_in = size; + d_stream.next_out = &gz_ptr[0]; + d_stream.avail_out = inflate_size; - err = inflateInit2(&d_stream, MAX_WBITS | 16); - if (err != Z_OK) { - LOG_FORMATS("inflateInit2 error: %d\n", err); - return false; - } - err = inflate(&d_stream, Z_FINISH); - if (err != Z_STREAM_END && err != Z_OK) { - LOG_FORMATS("inflate error: %d\n", err); - return false; - } - err = inflateEnd(&d_stream); - if (err != Z_OK) { - LOG_FORMATS("inflateEnd error: %d\n", err); - return false; - } - size = inflate_size; - img = gz_ptr; - - if (memcmp(&img[0], APD_HEADER, sizeof(APD_HEADER))) { - LOG_FORMATS("apd_dsk: floppy image has incorrect header\n"); - return false; + err = inflateInit2(&d_stream, MAX_WBITS | 16); + if (err != Z_OK) { + LOG_FORMATS("inflateInit2 error: %d\n", err); + return false; + } + err = inflate(&d_stream, Z_FINISH); + if (err != Z_STREAM_END && err != Z_OK) { + LOG_FORMATS("inflate error: %d\n", err); + return false; + } + err = inflateEnd(&d_stream); + if (err != Z_OK) { + LOG_FORMATS("inflateEnd error: %d\n", err); + return false; + } + size = inflate_size; + img = gz_ptr; } int data = 0x7d0; - for (int track = 0; track < 83; track++) { - for (int side = 0; side < 2; side++) { - uint32_t sdlen = little_endianize_int32(*(uint32_t *)(&img[(track * 2 + side) * 12 + 8 + 0x0])); - uint32_t ddlen = little_endianize_int32(*(uint32_t *)(&img[(track * 2 + side) * 12 + 8 + 0x4])); - uint32_t qdlen = little_endianize_int32(*(uint32_t *)(&img[(track * 2 + side) * 12 + 8 + 0x8])); + for (int track = 0; track < 166; track++) { + uint32_t sdlen = little_endianize_int32(*(uint32_t *)(&img[(track * 12) + 8 + 0x0])); + uint32_t ddlen = little_endianize_int32(*(uint32_t *)(&img[(track * 12) + 8 + 0x4])); + uint32_t qdlen = little_endianize_int32(*(uint32_t *)(&img[(track * 12) + 8 + 0x8])); - if (sdlen > 0) { - generate_track_from_bitstream(track, side, &img[data], sdlen, image); - data += (sdlen + 7) >> 3; - } - if (ddlen > 0) { - generate_track_from_bitstream(track, side, &img[data], ddlen, image); - data += (ddlen + 7) >> 3; - } - if (qdlen > 0) { - generate_track_from_bitstream(track, side, &img[data], qdlen, image); - data += (qdlen + 7) >> 3; - } + if (sdlen > 0) { + generate_track_from_bitstream(track / 2, track % 2, &img[data], sdlen, image); + data += (sdlen + 7) >> 3; + } + if (ddlen > 0) { + generate_track_from_bitstream(track / 2, track % 2, &img[data], ddlen, image); + data += (ddlen + 7) >> 3; + } + if (qdlen > 0) { + generate_track_from_bitstream(track / 2, track % 2, &img[data], qdlen, image); + data += (qdlen + 7) >> 3; } } image->set_variant(floppy_image::DSDD);