diff --git a/scripts/src/formats.lua b/scripts/src/formats.lua index 4606137b17c..994633e26b2 100644 --- a/scripts/src/formats.lua +++ b/scripts/src/formats.lua @@ -209,6 +209,18 @@ if (FORMATS["AP2_DSK"]~=null or _OPTIONS["with-tools"]) then } end +-------------------------------------------------- +-- +--@src/lib/formats/apd_dsk.h,FORMATS["APD_DSK"] = true +-------------------------------------------------- + +if (FORMATS["APD_DSK"]~=null or _OPTIONS["with-tools"]) then + files { + MAME_DIR.. "src/lib/formats/apd_dsk.cpp", + MAME_DIR.. "src/lib/formats/apd_dsk.h", + } +end + -------------------------------------------------- -- --@src/lib/formats/apf_apt.h,FORMATS["APF_APT"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 3ce6b20886c..b4bdbc7dcd9 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -729,6 +729,7 @@ FORMATS["ADAM_DSK"] = true FORMATS["AFS_DSK"] = true FORMATS["AMI_DSK"] = true FORMATS["AP2_DSK"] = true +FORMATS["APD_DSK"] = true FORMATS["APF_APT"] = true FORMATS["APOLLO_DSK"] = true FORMATS["APPLIX_DSK"] = true diff --git a/src/lib/formats/apd_dsk.cpp b/src/lib/formats/apd_dsk.cpp new file mode 100644 index 00000000000..cd5de8ad206 --- /dev/null +++ b/src/lib/formats/apd_dsk.cpp @@ -0,0 +1,124 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************* + + formats/apd_dsk.c + + Archimedes Protected Disk Image format + +*********************************************************************/ + +#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 GZ_HEADER[2] = { 0x1f, 0x8b }; + +apd_format::apd_format() +{ +} + +const char *apd_format::name() const +{ + return "apd"; +} + +const char *apd_format::description() const +{ + return "Archimedes Protected Disk Image"; +} + +const char *apd_format::extensions() const +{ + return "apd"; +} + +int apd_format::identify(io_generic *io, uint32_t form_factor) +{ + char h[8]; + + io_generic_read(io, h, 0, 8); + if (!memcmp(h, GZ_HEADER, sizeof(GZ_HEADER)) || !memcmp(h, APD_HEADER, sizeof(APD_HEADER))) { + return 100; + } + + return 0; +} + +bool apd_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) +{ + uint64_t size = io_generic_size(io); + std::vector img(size); + io_generic_read(io, &img[0], 0, size); + + int err; + std::vector gz_ptr; + z_stream d_stream; + 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); + + 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; + } + + 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])); + + 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; + } + } + } + image->set_variant(floppy_image::DSDD); + + return true; +} + +bool apd_format::supports_save() const +{ + return false; +} + +const floppy_format_type FLOPPY_APD_FORMAT = &floppy_image_format_creator; diff --git a/src/lib/formats/apd_dsk.h b/src/lib/formats/apd_dsk.h new file mode 100644 index 00000000000..3bf40055a7b --- /dev/null +++ b/src/lib/formats/apd_dsk.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************* + + formats/apd_dsk.h + + Archimedes Protected Disk Image format + +*********************************************************************/ + +#ifndef APD_DSK_H_ +#define APD_DSK_H_ + +#include "flopimg.h" + +class apd_format : public floppy_image_format_t { +public: + apd_format(); + + virtual const char *name() const override; + virtual const char *description() const override; + virtual const char *extensions() const override; + + virtual int identify(io_generic *io, uint32_t form_factor) override; + virtual bool load(io_generic *io, uint32_t form_factor, floppy_image *image) override; + virtual bool supports_save() const override; +}; + +extern const floppy_format_type FLOPPY_APD_FORMAT; + +#endif diff --git a/src/mame/drivers/aa310.cpp b/src/mame/drivers/aa310.cpp index f62ebc51a4b..00e468750b5 100644 --- a/src/mame/drivers/aa310.cpp +++ b/src/mame/drivers/aa310.cpp @@ -87,6 +87,7 @@ #include "cpu/arm/arm.h" #include "includes/archimds.h" #include "formats/acorn_dsk.h" +#include "formats/apd_dsk.h" #include "machine/i2cmem.h" #include "machine/ram.h" #include "machine/wd_fdc.h" @@ -351,7 +352,8 @@ INPUT_PORTS_END FLOPPY_FORMATS_MEMBER( aa310_state::floppy_formats ) FLOPPY_ACORN_ADFS_NEW_FORMAT, - FLOPPY_ACORN_ADFS_OLD_FORMAT + FLOPPY_ACORN_ADFS_OLD_FORMAT, + FLOPPY_APD_FORMAT FLOPPY_FORMATS_END static SLOT_INTERFACE_START( aa310_floppies )