diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/formats/aim_dsk.cpp | 108 | ||||
-rw-r--r-- | src/lib/formats/aim_dsk.h | 34 | ||||
-rw-r--r-- | src/lib/formats/ds9_dsk.cpp | 156 | ||||
-rw-r--r-- | src/lib/formats/ds9_dsk.h | 38 | ||||
-rw-r--r-- | src/lib/formats/dvk_mx_dsk.cpp | 177 | ||||
-rw-r--r-- | src/lib/formats/dvk_mx_dsk.h | 39 | ||||
-rw-r--r-- | src/lib/formats/flopimg.cpp | 40 | ||||
-rw-r--r-- | src/lib/formats/flopimg.h | 4 |
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 §or_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 §or_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 §or_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 §or_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 |