summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats
diff options
context:
space:
mode:
author ajrhacker <ajrhacker@users.noreply.github.com>2019-07-04 14:46:16 -0400
committer GitHub <noreply@github.com>2019-07-04 14:46:16 -0400
commit5035b85be074696f9db409ae86137b1ab7ff51a8 (patch)
treeef3fced86a11c5ecb8b3f532d825dd211bd5a317 /src/lib/formats
parent59f3d063f07d0f609ccc21b1413c9d98d7d1c6de (diff)
parenta152d1125fde01e80ab3e9cccd475a50c22c6316 (diff)
Merge pull request #5303 from shattered/_430d642ac2
agat: basic emulation of agat9 (video, apple compat mode, LLE floppy)
Diffstat (limited to 'src/lib/formats')
-rw-r--r--src/lib/formats/aim_dsk.cpp108
-rw-r--r--src/lib/formats/aim_dsk.h34
-rw-r--r--src/lib/formats/ds9_dsk.cpp156
-rw-r--r--src/lib/formats/ds9_dsk.h38
-rw-r--r--src/lib/formats/dvk_mx_dsk.cpp177
-rw-r--r--src/lib/formats/dvk_mx_dsk.h39
-rw-r--r--src/lib/formats/flopimg.cpp40
-rw-r--r--src/lib/formats/flopimg.h4
8 files changed, 596 insertions, 0 deletions
diff --git a/src/lib/formats/aim_dsk.cpp b/src/lib/formats/aim_dsk.cpp
new file mode 100644
index 00000000000..3bc2c2b5b5f
--- /dev/null
+++ b/src/lib/formats/aim_dsk.cpp
@@ -0,0 +1,108 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+/*********************************************************************
+
+ formats/aim_dsk.h
+
+ AIM disk images
+
+ References:
+ - http://www.torlus.com/floppy/forum/viewtopic.php?f=19&t=1385
+ - http://agatcomp.ru/Soft/agat.shtml
+
+*********************************************************************/
+
+#include <assert.h>
+
+#include "aim_dsk.h"
+
+
+aim_format::aim_format()
+{
+}
+
+
+const char *aim_format::name() const
+{
+ return "aim";
+}
+
+
+const char *aim_format::description() const
+{
+ return "AIM disk image";
+}
+
+
+const char *aim_format::extensions() const
+{
+ return "aim";
+}
+
+
+int aim_format::identify(io_generic *io, uint32_t form_factor)
+{
+ if (io_generic_size(io) == 2068480)
+ {
+ return 100;
+ }
+
+ return 0;
+}
+
+
+bool aim_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
+{
+ image->set_variant(floppy_image::DSQD);
+
+ const int tracks = 80;
+ const int track_size = 6464 * 2;
+ const int heads = 2;
+
+ for (int track = 0; track < tracks; track++)
+ {
+ for (int head = 0; head < heads; head++)
+ {
+ std::vector<uint8_t> track_data(track_size);
+ std::vector<uint32_t> raw_track_data;
+ int data_count = 0;
+ bool header = false;
+
+ // Read track
+ io_generic_read(io, &track_data[0], ( heads * track + head ) * track_size, track_size);
+
+ for (int offset = 0; offset < track_size; offset += 2)
+ {
+ switch (track_data[offset + 1] & 1)
+ {
+ case 0:
+ if (data_count == 0)
+ header = (track_data[offset] == 0x95) ? true : false;
+ data_count++;
+ mfm_w(raw_track_data, 8, track_data[offset]);
+ break;
+
+ case 1:
+ if (header && data_count < 11) // XXX hack
+ {
+ for (; data_count < 12; data_count++)
+ {
+ mfm_w(raw_track_data, 8, 0xaa);
+ }
+ }
+ raw_w(raw_track_data, 16, 0x8924);
+ raw_w(raw_track_data, 16, 0x5555);
+ data_count = 0;
+ break;
+ }
+ }
+
+ generate_track_from_levels(track, head, raw_track_data, 0, image);
+ }
+ }
+
+ return true;
+}
+
+
+const floppy_format_type FLOPPY_AIM_FORMAT = &floppy_image_format_creator<aim_format>;
diff --git a/src/lib/formats/aim_dsk.h b/src/lib/formats/aim_dsk.h
new file mode 100644
index 00000000000..75229875c69
--- /dev/null
+++ b/src/lib/formats/aim_dsk.h
@@ -0,0 +1,34 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+/*********************************************************************
+
+ formats/aim_dsk.h
+
+ AIM disk images
+
+*********************************************************************/
+
+#ifndef AIM_DSK_H
+#define AIM_DSK_H
+
+#include "flopimg.h"
+
+/**************************************************************************/
+
+class aim_format : public floppy_image_format_t
+{
+public:
+ aim_format();
+
+ 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 const char *name() const override;
+ virtual const char *description() const override;
+ virtual const char *extensions() const override;
+ virtual bool supports_save() const override { return false; }
+};
+
+extern const floppy_format_type FLOPPY_AIM_FORMAT;
+
+#endif /* AIM_DSK_H */
diff --git a/src/lib/formats/ds9_dsk.cpp b/src/lib/formats/ds9_dsk.cpp
new file mode 100644
index 00000000000..578d01a2cca
--- /dev/null
+++ b/src/lib/formats/ds9_dsk.cpp
@@ -0,0 +1,156 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+/**********************************************************************
+
+ formats/ds9_dsk.cpp
+
+ Floppies used by Agat-9 840KB controller
+
+ http://agatcomp.ru/Reading/docs/es5323.txt
+
+ https://github.com/sintech/AGAT/blob/master/docs/agat-840k-format.txt
+
+ http://www.torlus.com/floppy/forum/viewtopic.php?f=19&t=1385
+
+************************************************************************/
+
+#include <assert.h>
+
+#include "formats/ds9_dsk.h"
+
+
+static FLOPPY_IDENTIFY(ds9_dsk_identify)
+{
+ switch (floppy_image_size(floppy))
+ {
+ case (80 * 2 * 21 * 256):
+ case 860164:
+ case 860288:
+ *vote = 100;
+ break;
+
+ default:
+ *vote = 0;
+ break;
+ }
+
+ return FLOPPY_ERROR_SUCCESS;
+}
+
+static FLOPPY_CONSTRUCT(ds9_dsk_construct)
+{
+ struct basicdsk_geometry geometry;
+ memset(&geometry, 0, sizeof(geometry));
+ geometry.heads = 2;
+ geometry.first_sector_id = 0;
+ geometry.sector_length = 256;
+ geometry.tracks = 80;
+ geometry.sectors = 21;
+ return basicdsk_construct(floppy, &geometry);
+}
+
+LEGACY_FLOPPY_OPTIONS_START( ds9 )
+ LEGACY_FLOPPY_OPTION( ds9_dsk, "ds9,dsk,raw", "Agat 840K DSK image",
+ ds9_dsk_identify, ds9_dsk_construct, nullptr, nullptr)
+LEGACY_FLOPPY_OPTIONS_END
+
+// exactly 6500 bytes
+const floppy_image_format_t::desc_e ds9_format::ds9_desc[] = {
+ /* 01 */ { MFM, 0xaa, 32 }, // GAP1
+ /* 02 */ { SECTOR_LOOP_START, 0, 20 }, // 21 sectors
+ /* 03 */ { RAWBITS, 0x8924, 16 }, // sync mark: xA4, 2 us zero level interval, 0xFF
+ /* 04 */ { RAWBITS, 0x5555, 16 },
+ /* 05 */ { MFM, 0x95, 1 }, // address field prologue
+ /* 06 */ { MFM, 0x6a, 1 },
+ /* 07 */ { MFM, 0xfe, 1 }, // volume number
+ /* 08 */ { OFFSET_ID },
+ /* 09 */ { SECTOR_ID },
+ /* 10 */ { MFM, 0x5a, 1 }, // address field epilogue
+ /* 11 */ { MFM, 0xaa, 5 }, // GAP2 (min 4 bytes)
+ /* 12 */ { RAWBITS, 0x8924, 16 }, // sync mark
+ /* 13 */ { RAWBITS, 0x5555, 16 },
+ /* 14 */ { MFM, 0x6a, 1 }, // data field prologue
+ /* 15 */ { MFM, 0x95, 1 },
+ /* 16 */ { SECTOR_DATA_DS9, -1 },
+ /* 17 */ { MFM, 0x5a, 1 }, // data field epilogue
+ /* 18 */ { MFM, 0xaa, 33 }, // GAP3
+ /* 19 */ { SECTOR_LOOP_END },
+ /* 20 */ { END }
+};
+
+ds9_format::ds9_format()
+{
+}
+
+const char *ds9_format::name() const
+{
+ return "a9dsk";
+}
+
+const char *ds9_format::description() const
+{
+ return "Agat-9 840K floppy image";
+}
+
+const char *ds9_format::extensions() const
+{
+ return "ds9";
+}
+
+void ds9_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
+{
+ uint32_t expected_size = 0;
+ uint64_t size = io_generic_size(io);
+
+ head_count = 2;
+ track_count = 80;
+ sector_count = 21;
+ expected_size = 256 * track_count * head_count * sector_count;
+
+ if (size >= expected_size) // standard format has 860160 bytes
+ return;
+
+ track_count = head_count = sector_count = 0;
+}
+
+int ds9_format::identify(io_generic *io, uint32_t form_factor)
+{
+ uint8_t track_count, head_count, sector_count;
+ find_size(io, track_count, head_count, sector_count);
+
+ if (track_count) return 50;
+
+ return 0;
+}
+
+bool ds9_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
+{
+ uint8_t track_count, head_count, sector_count;
+ find_size(io, track_count, head_count, sector_count);
+ if (track_count == 0) return false;
+
+ uint8_t sectdata[21 * 256];
+ desc_s sectors[21];
+ for (int i = 0; i < sector_count; i++)
+ {
+ sectors[i].data = sectdata + 256 * i;
+ sectors[i].size = 256;
+ sectors[i].sector_id = i;
+ }
+
+ int track_size = sector_count * 256;
+ for (int track = 0; track < track_count; track++)
+ {
+ for (int head = 0; head < head_count; head++)
+ {
+ io_generic_read(io, sectdata, (track * head_count + head) * track_size, track_size);
+ generate_track(ds9_desc, track, head, sectors, sector_count, 104000, image);
+ }
+ }
+
+ image->set_variant(floppy_image::DSQD);
+
+ return true;
+}
+
+const floppy_format_type FLOPPY_DS9_FORMAT = &floppy_image_format_creator<ds9_format>;
diff --git a/src/lib/formats/ds9_dsk.h b/src/lib/formats/ds9_dsk.h
new file mode 100644
index 00000000000..540c49a7ce7
--- /dev/null
+++ b/src/lib/formats/ds9_dsk.h
@@ -0,0 +1,38 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+/*********************************************************************
+
+ formats/ds9_dsk.h
+
+*********************************************************************/
+
+#ifndef DS9_DSK_H_
+#define DS9_DSK_H_
+
+#include "flopimg.h"
+#include "formats/basicdsk.h"
+
+LEGACY_FLOPPY_OPTIONS_EXTERN(ds9);
+
+class ds9_format : public floppy_image_format_t
+{
+public:
+ ds9_format();
+
+ 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 const char *name() const override;
+ virtual const char *description() const override;
+ virtual const char *extensions() const override;
+ virtual bool supports_save() const override { return false; }
+
+ static const desc_e ds9_desc[];
+
+private:
+ void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
+};
+
+extern const floppy_format_type FLOPPY_DS9_FORMAT;
+
+#endif /* DS9_DSK_H_ */
diff --git a/src/lib/formats/dvk_mx_dsk.cpp b/src/lib/formats/dvk_mx_dsk.cpp
new file mode 100644
index 00000000000..af7d883e4d6
--- /dev/null
+++ b/src/lib/formats/dvk_mx_dsk.cpp
@@ -0,0 +1,177 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+/**********************************************************************
+
+ formats/dvk_mx_dsk.cpp
+
+ Floppies used by DVK MX: controller
+
+ http://torlus.com/floppy/forum/viewtopic.php?f=19&t=1384
+
+ Track format is almost entirely driver-dependent (only sync word
+ 0x00f3 is mandatory), because hardware always reads or writes
+ entire track. 'old' format is used by stock driver, 'new' --
+ by 3rd party one. Formatting tools produce yet other variants...
+
+ Floppy drives were 40- and 80-track, double-sided. 'new' driver
+ also supports single-sided floppies.
+
+************************************************************************/
+
+#include <assert.h>
+
+#include "flopimg.h"
+#include "formats/dvk_mx_dsk.h"
+
+const floppy_image_format_t::desc_e dvk_mx_format::dvk_mx_new_desc[] = {
+ /* 01 */ { FM, 0x00, 8*2 }, // eight 0x0000 words
+ /* 03 */ { FM, 0x00, 1 },
+ /* 02 */ { FM, 0xf3, 1 }, // word 0x00f3
+ /* 05 */ { FM, 0x00, 1 },
+ /* 04 */ { TRACK_ID_FM }, // track number word
+ /* 05 */ { SECTOR_LOOP_START, 0, 10 }, // 11 sectors
+ /* 07 */ { SECTOR_DATA_MX, -1 },
+ /* 10 */ { SECTOR_LOOP_END },
+ /* 13 */ { FM, 0x83, 1 },
+ /* 12 */ { OFFSET_ID_FM },
+ /* 15 */ { FM, 0x83, 1 },
+ /* 14 */ { OFFSET_ID_FM },
+ /* 17 */ { FM, 0x83, 1 },
+ /* 16 */ { OFFSET_ID_FM },
+ /* 18 */ { END }
+};
+
+const floppy_image_format_t::desc_e dvk_mx_format::dvk_mx_old_desc[] = {
+ /* 01 */ { FM, 0x00, 30*2 },
+ /* 03 */ { FM, 0x00, 1 },
+ /* 02 */ { FM, 0xf3, 1 }, // word 0x00f3
+ /* 05 */ { FM, 0x00, 1 },
+ /* 04 */ { TRACK_ID_FM }, // track number word
+ /* 06 */ { SECTOR_LOOP_START, 0, 10 }, // 11 sectors
+ /* 07 */ { SECTOR_DATA_MX, -1 },
+ /* 10 */ { SECTOR_LOOP_END },
+ /* 13 */ { FM, 0x83, 1 },
+ /* 11 */ { FM, 0x01, 1 },
+ /* 15 */ { FM, 0x83, 1 },
+ /* 14 */ { FM, 0x01, 1 },
+ /* 16 */ { END }
+};
+
+dvk_mx_format::dvk_mx_format()
+{
+}
+
+const char *dvk_mx_format::name() const
+{
+ return "mx";
+}
+
+const char *dvk_mx_format::description() const
+{
+ return "DVK MX: floppy image";
+}
+
+const char *dvk_mx_format::extensions() const
+{
+ return "mx";
+}
+
+bool dvk_mx_format::supports_save() const
+{
+ return false;
+}
+
+void dvk_mx_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
+{
+ uint64_t size = io_generic_size(io);
+
+ switch (size)
+ {
+ case 112640:
+ track_count = 40;
+ sector_count = 11;
+ head_count = 1;
+ break;
+ case 225280:
+ track_count = 40;
+ sector_count = 11;
+ head_count = 2;
+ break;
+ case 450560:
+ track_count = 80;
+ sector_count = 11;
+ head_count = 2;
+ break;
+ default:
+ track_count = head_count = sector_count = 0;
+ break;
+ }
+}
+
+int dvk_mx_format::identify(io_generic *io, uint32_t form_factor)
+{
+ uint8_t track_count, head_count, sector_count;
+
+ find_size(io, track_count, head_count, sector_count);
+
+ if (track_count)
+ {
+ uint8_t sectdata[512];
+ io_generic_read(io, sectdata, 512, 512);
+ // check value in RT-11 home block. see src/tools/imgtool/modules/rt11.cpp
+ if (pick_integer_le(sectdata, 0724, 2) == 6)
+ return 100;
+ else
+ return 75;
+
+ }
+
+ return 0;
+}
+
+bool dvk_mx_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
+{
+ uint8_t track_count, head_count, sector_count;
+
+ find_size(io, track_count, head_count, sector_count);
+ if (track_count == 0) return false;
+
+ uint8_t sectdata[11 * 256];
+ desc_s sectors[11];
+ for (int i = 0; i < sector_count; i++)
+ {
+ sectors[i].data = sectdata + 256 * i;
+ sectors[i].size = 256;
+ sectors[i].sector_id = i;
+ }
+
+ int track_size = sector_count * 256;
+ for (int track = 0; track < track_count; track++)
+ {
+ for (int head = 0; head < head_count; head++)
+ {
+ io_generic_read(io, sectdata, (track * head_count + head) * track_size, track_size);
+ generate_track(dvk_mx_new_desc, track, head, sectors, sector_count, 45824, image);
+ }
+ }
+
+ if (head_count == 1)
+ {
+ image->set_variant(floppy_image::SSDD);
+ }
+ else
+ {
+ if (track_count > 40)
+ {
+ image->set_variant(floppy_image::DSQD);
+ }
+ else
+ {
+ image->set_variant(floppy_image::DSDD);
+ }
+ }
+
+ return true;
+}
+
+const floppy_format_type FLOPPY_DVK_MX_FORMAT = &floppy_image_format_creator<dvk_mx_format>;
diff --git a/src/lib/formats/dvk_mx_dsk.h b/src/lib/formats/dvk_mx_dsk.h
new file mode 100644
index 00000000000..a95b635588c
--- /dev/null
+++ b/src/lib/formats/dvk_mx_dsk.h
@@ -0,0 +1,39 @@
+// license:BSD-3-Clause
+// copyright-holders:Sergey Svishchev
+/*********************************************************************
+
+ formats/dvk_mx_dsk.h
+
+*********************************************************************/
+
+#ifndef DVK_MX_DSK_H_
+#define DVK_MX_DSK_H_
+
+#pragma once
+
+#include "flopimg.h"
+#include "imageutl.h"
+
+class dvk_mx_format : public floppy_image_format_t
+{
+public:
+ dvk_mx_format();
+
+ 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 const char *name() const override;
+ virtual const char *description() const override;
+ virtual const char *extensions() const override;
+ virtual bool supports_save() const override;
+
+ static const desc_e dvk_mx_old_desc[];
+ static const desc_e dvk_mx_new_desc[];
+
+private:
+ void find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count);
+};
+
+extern const floppy_format_type FLOPPY_DVK_MX_FORMAT;
+
+#endif /* DVK_MX_DSK_H_ */
diff --git a/src/lib/formats/flopimg.cpp b/src/lib/formats/flopimg.cpp
index 3d05ec38d03..ea812506f50 100644
--- a/src/lib/formats/flopimg.cpp
+++ b/src/lib/formats/flopimg.cpp
@@ -1038,6 +1038,7 @@ bool floppy_image_format_t::type_data_mfm(int type, int p1, const gen_crc_info *
type == SIZE_ID ||
type == OFFSET_ID_O ||
type == OFFSET_ID_E ||
+ type == OFFSET_ID_FM ||
type == SECTOR_ID_O ||
type == SECTOR_ID_E ||
type == REMAIN_O ||
@@ -1521,6 +1522,14 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he
mfm_half_w(buffer, 6, track*2+head);
break;
+ case OFFSET_ID_FM:
+ fm_w(buffer, 8, track*2+head);
+ break;
+
+ case OFFSET_ID:
+ mfm_w(buffer, 8, track*2+head);
+ break;
+
case SECTOR_ID_O:
mfm_half_w(buffer, 7, sector_idx);
break;
@@ -1650,6 +1659,37 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he
break;
}
+ case SECTOR_DATA_MX: {
+ const desc_s *csect = sect + (desc[index].p1 >= 0 ? desc[index].p1 : sector_idx);
+ uint16_t cksum = 0, data;
+ for(int i=0; i < csect->size; i+=2)
+ {
+ data = csect->data[i+1];
+ fm_w(buffer, 8, data);
+ data = (data << 8) | csect->data[i];
+ fm_w(buffer, 8, csect->data[i]);
+ cksum += data;
+ }
+ fm_w(buffer, 16, cksum);
+ break;
+ }
+
+ case SECTOR_DATA_DS9: {
+ const desc_s *csect = sect + (desc[index].p1 >= 0 ? desc[index].p1 : sector_idx);
+ uint8_t data;
+ int cksum = 0;
+ for(int i=0; i != csect->size; i++)
+ {
+ if (cksum > 255) { cksum++; cksum &= 255; }
+ data = csect->data[i];
+ mfm_w(buffer, 8, data);
+ cksum += data;
+ }
+ cksum &= 255;
+ mfm_w(buffer, 8, cksum);
+ break;
+ }
+
default:
printf("%d.%d.%d (%d) unhandled\n", desc[index].type, desc[index].p1, desc[index].p2, index);
break;
diff --git a/src/lib/formats/flopimg.h b/src/lib/formats/flopimg.h
index 8430ae8150b..d5edd6b0315 100644
--- a/src/lib/formats/flopimg.h
+++ b/src/lib/formats/flopimg.h
@@ -333,6 +333,8 @@ protected:
SECTOR_INFO_GCR6, //!< Sector info byte, gcr6-encoded
OFFSET_ID_O, //!< Offset (track*2+head) byte, odd bits, mfm-encoded
OFFSET_ID_E, //!< Offset (track*2+head) byte, even bits, mfm-encoded
+ OFFSET_ID_FM, //!< Offset (track*2+head) byte, fm-encoded
+ OFFSET_ID, //!< Offset (track*2+head) byte, mfm-encoded
SECTOR_ID_O, //!< Sector id byte, odd bits, mfm-encoded
SECTOR_ID_E, //!< Sector id byte, even bits, mfm-encoded
REMAIN_O, //!< Remaining sector count, odd bits, mfm-encoded, total sector count in p1
@@ -345,6 +347,8 @@ protected:
SECTOR_DATA_GCR5, //!< Sector data to gcr5-encode, which in p1, -1 for the current one per the sector id
SECTOR_DATA_MAC, //!< Transformed sector data + checksum, mac style, id in p1, -1 for the current one per the sector id
SECTOR_DATA_8N1, //!< Sector data to 8N1-encode, which in p1, -1 for the current one per the sector id
+ SECTOR_DATA_MX, //!< Sector data to MX-encode, which in p1, -1 for the current one per the sector id
+ SECTOR_DATA_DS9, //!< Sector data to DS9-encode, which in p1, -1 for the current one per the sector id
CRC_CCITT_START, //!< Start a CCITT CRC calculation, with the usual x^16 + x^12 + x^5 + 1 (11021) polynomial, p1 = crc id
CRC_CCITT_FM_START, //!< Start a CCITT CRC calculation, with the usual x^16 + x^12 + x^5 + 1 (11021) polynomial, p1 = crc id