diff options
author | 2020-03-02 16:45:49 +0300 | |
---|---|---|
committer | 2020-03-02 20:21:04 +0300 | |
commit | c155d424ac66496b15055ffacb9e9731102a454a (patch) | |
tree | 88723514e2124570ae1018d86bc4a15dd5cdebd9 | |
parent | 0a6807102b1a6512d66748f034256bd24bcae1a4 (diff) |
ibmxdf_dsk: IBM Extended Disk Format support (nw)
-rw-r--r-- | hash/ibm5170.xml | 6 | ||||
-rw-r--r-- | scripts/src/formats.lua | 12 | ||||
-rw-r--r-- | src/devices/bus/isa/fdc.cpp | 4 | ||||
-rw-r--r-- | src/lib/formats/ibmxdf_dsk.cpp | 262 | ||||
-rw-r--r-- | src/lib/formats/ibmxdf_dsk.h | 45 | ||||
-rw-r--r-- | src/tools/floptool.cpp | 2 |
6 files changed, 324 insertions, 7 deletions
diff --git a/hash/ibm5170.xml b/hash/ibm5170.xml index 570f2cf57f5..a7ee923967f 100644 --- a/hash/ibm5170.xml +++ b/hash/ibm5170.xml @@ -2113,7 +2113,6 @@ </part> </software> - <!-- IBM Extended Density Format not supported --> <software name="pcdos7fr" cloneof="pcdos7" supported="no"> <description>PC DOS 7.0 (French)</description> <year>1995</year> @@ -2145,7 +2144,6 @@ </part> </software> - <!-- IBM Extended Density Format not supported --> <software name="pcdos7ja" cloneof="pcdos7" supported="no"> <description>PC DOS 7.0 (Japanese)</description> <year>1995</year> @@ -2198,7 +2196,6 @@ </part> </software> - <!-- IBM Extended Density Format not supported --> <software name="pcdos7ko" cloneof="pcdos7" supported="no"> <description>PC DOS 7.0 (Korean)</description> <year>1995</year> @@ -2246,7 +2243,6 @@ </part> </software> - <!-- IBM Extended Density Format not supported --> <software name="pcdos7ru" cloneof="pcdos7" supported="no"> <description>PC DOS 7.0 (Russian)</description> <year>1995</year> @@ -2279,7 +2275,6 @@ </part> </software> - <!-- IBM Extended Density Format not supported --> <software name="pcdos7engb" cloneof="pcdos7" supported="no"> <description>PC DOS 7.0 (UK English)</description> <year>1995</year> @@ -2570,7 +2565,6 @@ </part> </software> - <!-- IBM Extended Density Format not supported --> <software name="pcdos2kzhs" cloneof="pcdos2k" supported="no"> <description>IBM PC DOS 2000 (Simplified Chinese)</description> <year>1998</year> diff --git a/scripts/src/formats.lua b/scripts/src/formats.lua index e09d34c2e33..c234f37808b 100644 --- a/scripts/src/formats.lua +++ b/scripts/src/formats.lua @@ -1363,6 +1363,18 @@ end -------------------------------------------------- -- +--@src/lib/formats/ibmxdf_dsk.h,FORMATS["IBMXDF_DSK"] = true +-------------------------------------------------- + +if (FORMATS["IBMXDF_DSK"]~=null or _OPTIONS["with-tools"]) then + files { + MAME_DIR.. "src/lib/formats/ibmxdf_dsk.cpp", + MAME_DIR.. "src/lib/formats/ibmxdf_dsk.h", + } +end + +-------------------------------------------------- +-- --@src/lib/formats/p6001_cas.h,FORMATS["P6001_CAS"] = true -------------------------------------------------- diff --git a/src/devices/bus/isa/fdc.cpp b/src/devices/bus/isa/fdc.cpp index 3c601e42ce2..3ec6db240d1 100644 --- a/src/devices/bus/isa/fdc.cpp +++ b/src/devices/bus/isa/fdc.cpp @@ -12,11 +12,13 @@ #include "machine/pc_fdc.h" #include "formats/pc_dsk.h" #include "formats/naslite_dsk.h" +#include "formats/ibmxdf_dsk.h" FLOPPY_FORMATS_MEMBER( isa8_fdc_device::floppy_formats ) FLOPPY_PC_FORMAT, - FLOPPY_NASLITE_FORMAT + FLOPPY_NASLITE_FORMAT, + FLOPPY_IBMXDF_FORMAT FLOPPY_FORMATS_END static void pc_dd_floppies(device_slot_interface &device) diff --git a/src/lib/formats/ibmxdf_dsk.cpp b/src/lib/formats/ibmxdf_dsk.cpp new file mode 100644 index 00000000000..4f609475a51 --- /dev/null +++ b/src/lib/formats/ibmxdf_dsk.cpp @@ -0,0 +1,262 @@ +// license:BSD-3-Clause +// copyright-holders:Sergey Svishchev +/********************************************************************* + + formats/ibmxdf_dsk.c + + IBM Extended Density Format + + References: + - http://www.os2museum.com/wp/the-xdf-diskette-format/ + - https://fdutils.linux.lu/Fdutils.html#SEC47 and xdfcopy.c + + Mapping XDF disk image to physical sectors on a 3.5" disk: + + First track uses standard 512-byte sectors: + - lbn 0 (boot sector) = 0.129 (head.sector) + - lbn 1-11 (FAT) = 0.130-0.139, then 1.129 + - lbn 12-19 (aux FS) = 0.1-0.8 + - lbn 20-22 = padding, not written to disk + - lbn 23-36 (root directory) = 1.130-1.143 + - lbn 37-41 = padding, not written to disk + - lbn 42-45 (start of data area) = 1.144-1.147 + + All other tracks use mixed size sectors, sequenced like so: + 0.131, 0.132, 1.134, 0.130, 1.130, 0.134, 1.132, 1.131 + + To do: + - 5.25 HD and 3.5 ED formats + - replace magic numbers + +*********************************************************************/ + +#include <assert.h> + +#include "emu.h" // emu_fatalerror +#include "formats/ibmxdf_dsk.h" + +ibmxdf_format::ibmxdf_format() : wd177x_format(formats) +{ +} + +const char *ibmxdf_format::name() const +{ + return "xdf"; +} + +const char *ibmxdf_format::description() const +{ + return "IBM XDF disk image"; +} + +const char *ibmxdf_format::extensions() const +{ + return "xdf,img"; +} + +int ibmxdf_format::identify(io_generic *io, uint32_t form_factor) +{ + int type = find_size(io, form_factor); + + if (type != -1) + return 75; + return 0; +} + +int ibmxdf_format::find_size(io_generic *io, uint32_t form_factor) +{ + uint64_t size = io_generic_size(io); + + if (size != 1884160) + return -1; + + return 0; +} + +int ibmxdf_format::get_image_offset(const format &f, int head, int track) +{ + return (2 * track) * compute_track_size(formats[0]); +} + +const wd177x_format::format &ibmxdf_format::get_track_format(const format &f, int head, int track) +{ + int n = -1; + + for (int i = 0; formats[i].form_factor; i++) { + if (&formats[i] == &f) { + n = i; + break; + } + } + + if (n < 0) { + LOG_FORMATS("Error format not found\n"); + return f; + } + + if (head >= f.head_count) { + LOG_FORMATS("Error invalid head %d\n", head); + return f; + } + + if (track >= f.track_count) { + LOG_FORMATS("Error invalid track %d\n", track); + return f; + } + + if (track > 0) { + if (head == 1) { + const format &fh1 = formats_head1[n]; + if (!fh1.form_factor) { + LOG_FORMATS("Error expected a head 1 format\n"); + return f; + } + return fh1; + } + return f; + } + + // Track 0 + + if (head == 1) { + const format &fh1t0 = formats_head1_track0[n]; + if (fh1t0.form_factor) { + return fh1t0; + } + const format &fh1 = formats_head1[n]; + if (fh1.form_factor) { + return fh1; + } + LOG_FORMATS("Error expected a head 1 format\n"); + return f; + } + + // Head 0 + + const format &ft0 = formats_track0[n]; + if (ft0.form_factor) { + return ft0; + } + + return f; +} + + +// Unverified gap sizes +const ibmxdf_format::format ibmxdf_format::formats[] = { + { + floppy_image::FF_35, floppy_image::DSHD, floppy_image::MFM, + 1000, 4, 80, 2, 0, { 1024, 512, 2048, 8192 }, -1, { 131, 130, 132, 134 }, 50, 22, 74 + }, + {} +}; + +const ibmxdf_format::format ibmxdf_format::formats_head1[] = { + { + floppy_image::FF_35, floppy_image::DSHD, floppy_image::MFM, + 1000, 4, 80, 2, 0, { 2048, 512, 1024, 8192 }, -1, { 132, 130, 131, 134 }, 50, 22, 74 + }, + {} +}; + +const ibmxdf_format::format ibmxdf_format::formats_track0[] = { + { + floppy_image::FF_35, floppy_image::DSHD, floppy_image::MFM, + 1000, 19, 80, 2, 512, {}, -1, { 1, 138, 129, 139, 130, 2, 131, 3, 132, 4, 133, 5, 134, 6, 135, 7, 136, 8, 137 }, 50, 22, 74 + }, + {} +}; + +const ibmxdf_format::format ibmxdf_format::formats_head1_track0[] = { + { + floppy_image::FF_35, floppy_image::DSHD, floppy_image::MFM, + 1000, 19, 80, 2, 512, {}, -1, { 144, 135, 145, 136, 146, 137, 147, 138, 129, 139, 130, 140, 131, 141, 132, 142, 133, 143, 134 }, 50, 22, 74 + }, + {} +}; + +bool ibmxdf_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) +{ + int type = find_size(io, form_factor); + if(type == -1) + return false; + + const format &f = formats[type]; + + for(int track=0; track < f.track_count; track++) + for(int head=0; head < f.head_count; head++) { + uint8_t sectdata[23 * 2 * 512]; // XXX magic + desc_s sectors[40]; + floppy_image_format_t::desc_e *desc; + int current_size; + int end_gap_index; + const format &tf = get_track_format(f, head, track); + + desc = get_desc_mfm(tf, current_size, end_gap_index); + + int total_size = 200000000/tf.cell_size; + int remaining_size = total_size - current_size; + if(remaining_size < 0) + throw emu_fatalerror("ibmxdf_format: Incorrect track layout, max_size=%d, current_size=%d", total_size, current_size); + + // Fixup the end gap + desc[end_gap_index].p2 = remaining_size / 16; + desc[end_gap_index + 1].p2 = remaining_size & 15; + desc[end_gap_index + 1].p1 >>= 16-(remaining_size & 15); + + desc[16].p1 = get_track_dam_mfm(tf, head, track); + + build_sector_description(tf, sectdata, sectors, track, head); + int track_size = compute_track_size(f) * 2; // read both sides at once + io_generic_read(io, sectdata, get_image_offset(f, head, track), track_size); + generate_track(desc, track, head, sectors, tf.sector_count, total_size, image); + } + + image->set_variant(f.variant); + + return true; +} + +static const int offsets[2][4] = { { 0, 11264, 1024, 12288 }, { 20480, 11776, 22528, 3072 } }; // XXX magic + +void ibmxdf_format::build_sector_description(const format &f, uint8_t *sectdata, desc_s *sectors, int track, int head) const +{ + switch (track) + { + case 0: + if (head == 0) { + for(int i=0; i<f.sector_count; i++) { + if (f.per_sector_id[i] < 129) // aux fs + sectors[i].data = sectdata + f.sector_base_size * (f.per_sector_id[i] + 11); + else + sectors[i].data = sectdata + f.sector_base_size * (f.per_sector_id[i] - 129); + sectors[i].size = f.sector_base_size; + sectors[i].sector_id = f.per_sector_id[i]; + } + } + else { + for(int i=0; i<f.sector_count; i++) { + if (f.per_sector_id[i] == 129) + sectors[i].data = sectdata + f.sector_base_size * 11; + else if (f.per_sector_id[i] < 144) + sectors[i].data = sectdata + f.sector_base_size * (f.per_sector_id[i] - 130 + 23); + else // skip 5 sectors marked bad in the FAT + sectors[i].data = sectdata + f.sector_base_size * (f.per_sector_id[i] - 130 + 28); + sectors[i].size = f.sector_base_size; + sectors[i].sector_id = f.per_sector_id[i]; + } + } + break; + + default: + for(int i=0; i<f.sector_count; i++) { + sectors[i].data = sectdata + offsets[head][i]; + sectors[i].size = f.per_sector_size[i]; + sectors[i].sector_id = f.per_sector_id[i]; + } + break; + } +} + +const floppy_format_type FLOPPY_IBMXDF_FORMAT = &floppy_image_format_creator<ibmxdf_format>; + diff --git a/src/lib/formats/ibmxdf_dsk.h b/src/lib/formats/ibmxdf_dsk.h new file mode 100644 index 00000000000..494dbca4bfd --- /dev/null +++ b/src/lib/formats/ibmxdf_dsk.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Sergey Svishchev +/********************************************************************* + + formats/xdf_dsk.h + + IBM Extended Density Format + +*********************************************************************/ +#ifndef MAME_FORMATS_IBMXDF_DSK_H +#define MAME_FORMATS_IBMXDF_DSK_H + +#pragma once + +#include "wd177x_dsk.h" + +class ibmxdf_format : public wd177x_format +{ +public: + ibmxdf_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 { return false; } + + virtual int find_size(io_generic *io, uint32_t form_factor) override; + virtual int get_image_offset(const format &f, int head, int track) override; + virtual const wd177x_format::format &get_track_format(const format &f, int head, int track) override; + +private: + static const format formats[]; + static const format formats_head1[]; + static const format formats_track0[]; + static const format formats_head1_track0[]; + + virtual void build_sector_description(const format &d, uint8_t *sectdata, desc_s *sectors, int track, int head) const override; +}; + +extern const floppy_format_type FLOPPY_IBMXDF_FORMAT; + +#endif // MAME_FORMATS_IBMXDF_DSK_H diff --git a/src/tools/floptool.cpp b/src/tools/floptool.cpp index a791ceb4190..6102304bbf3 100644 --- a/src/tools/floptool.cpp +++ b/src/tools/floptool.cpp @@ -38,6 +38,7 @@ #include "formats/cqm_dsk.h" #include "formats/pc_dsk.h" #include "formats/naslite_dsk.h" +#include "formats/ibmxdf_dsk.h" #include "formats/ap_dsk35.h" #include "formats/ap2_dsk.h" @@ -82,6 +83,7 @@ static floppy_format_type floppy_formats[] = { FLOPPY_CQM_FORMAT, FLOPPY_PC_FORMAT, FLOPPY_NASLITE_FORMAT, + FLOPPY_IBMXDF_FORMAT, FLOPPY_DC42_FORMAT, FLOPPY_A216S_FORMAT, |