summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/ds9_dsk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/formats/ds9_dsk.cpp')
-rw-r--r--src/lib/formats/ds9_dsk.cpp156
1 files changed, 156 insertions, 0 deletions
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>;