summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author 68bit <info@68bit.org>2019-07-31 11:26:04 +1000
committer 68bit <info@68bit.org>2019-08-13 13:42:13 +1000
commit10f480911da66a56f5e70667c4019468ba04faf2 (patch)
tree3b91cb9ce3097928df6ad513b7a37d6133d5249e
parent6bf8519cf5de98bd85d1e766a795d0f165766749 (diff)
swtpc09: add a UniFLEX specific floppy format.
The UniFLEX disk format is not compatible with the Flex format. Significantly it does not use a mix of single density for booting on some double density disks which makes it simpler - hardware required a new boot ROM to run UniFLEX. Further, the UniFLEX sector size is 512 bytes versus 256 for Flex, and the UniFLEX 'SIR' info sector record is completely different to the info on Flex disk, and the file system format is also not at all compatible. Thus the UniFlex format can rely largely on the WD17xx format, with an overload to handle the sector numbering on the second side continuing from the first side (one feature in common with the Flex format). This gives a quick 'save' capability and shares code. Support for 8" disks is included as this was the initial distribution format and the only one found so far.
-rw-r--r--scripts/src/formats.lua12
-rw-r--r--src/lib/formats/uniflex_dsk.cpp150
-rw-r--r--src/lib/formats/uniflex_dsk.h32
-rw-r--r--src/tools/floptool.cpp8
4 files changed, 201 insertions, 1 deletions
diff --git a/scripts/src/formats.lua b/scripts/src/formats.lua
index 5ae22a556c8..6bb724e3e40 100644
--- a/scripts/src/formats.lua
+++ b/scripts/src/formats.lua
@@ -835,6 +835,18 @@ end
--------------------------------------------------
--
+--@src/lib/formats/uniflex_dsk.h,FORMATS["UNIFLEX_DSK"] = true
+--------------------------------------------------
+
+if (FORMATS["UNIFLEX_DSK"]~=null or _OPTIONS["with-tools"]) then
+ files {
+ MAME_DIR.. "src/lib/formats/uniflex_dsk.cpp",
+ MAME_DIR.. "src/lib/formats/uniflex_dsk.h",
+ }
+end
+
+--------------------------------------------------
+--
--@src/lib/formats/fm7_cas.h,FORMATS["FM7_CAS"] = true
--------------------------------------------------
diff --git a/src/lib/formats/uniflex_dsk.cpp b/src/lib/formats/uniflex_dsk.cpp
new file mode 100644
index 00000000000..646fdcc68b1
--- /dev/null
+++ b/src/lib/formats/uniflex_dsk.cpp
@@ -0,0 +1,150 @@
+// license:BSD-3-Clause
+// copyright-holders:68bit
+/*
+ * uniflex_dsk.c - UniFLEX compatible disk images
+ *
+ * The UniFLEX floppy disk format is distinctily different to the FLEX format,
+ * the sector size is 512 byte sectors versus 256 byte sectors and the format
+ * of the disk information is different, and the file system format is
+ * different.
+ */
+
+#include "uniflex_dsk.h"
+#include "formats/imageutl.h"
+
+uniflex_format::uniflex_format() : wd177x_format(formats)
+{
+}
+
+const char *uniflex_format::name() const
+{
+ return "uniflex";
+}
+
+const char *uniflex_format::description() const
+{
+ return "UniFLEX compatible disk image";
+}
+
+const char *uniflex_format::extensions() const
+{
+ return "dsk";
+}
+
+int uniflex_format::identify(io_generic *io, uint32_t form_factor)
+{
+ int type = find_size(io, form_factor);
+
+ if (type != -1)
+ return 75;
+ return 0;
+}
+
+int uniflex_format::find_size(io_generic *io, uint32_t form_factor)
+{
+ uint64_t size = io_generic_size(io);
+ uint8_t sir[192];
+
+ // Look at the SIR sector, the second sector.
+ io_generic_read(io, sir, 1 * 512, sizeof(sir));
+
+ uint16_t fdn_block_count = pick_integer_be(sir, 0x10, 2);
+ uint32_t last_block_number = pick_integer_be(sir, 0x12, 3);
+ uint32_t free_block_count = pick_integer_be(sir, 0x15, 3);
+ uint16_t fdn_free_count = pick_integer_be(sir, 0x15, 2);
+
+ uint16_t volume_number = pick_integer_be(sir, 0x36, 2);
+ uint8_t disk_density = sir[0x3a];
+ uint8_t disk_side_info = sir[0x3b];
+
+ uint32_t volbc_start_addr = pick_integer_be(sir, 0x3c, 3);
+ uint16_t swap_size = pick_integer_be(sir, 0x3f, 2);
+
+ LOG_FORMATS("UniFLEX floppy dsk size %d\n", (uint32_t)size);
+ LOG_FORMATS(" time = %lu %lu\n", pick_integer_be(sir, 0x08, 4), pick_integer_be(sir, 0x0c, 4));
+ LOG_FORMATS(" fdn_block_count: %d\n", fdn_block_count);
+
+ LOG_FORMATS(" file system name: ");
+ for (int i = 0; i < 14; i++)
+ LOG_FORMATS(" %02x", sir[0x1a + i]);
+ LOG_FORMATS("\n");
+
+ LOG_FORMATS(" volume name: ");
+ for (int i = 0; i < 14; i++)
+ LOG_FORMATS(" %02x", sir[0x28 + i]);
+ LOG_FORMATS("\n");
+
+ LOG_FORMATS(" last_block_number: %d\n", last_block_number);
+ LOG_FORMATS(" free_block_count: %d\n", free_block_count);
+ LOG_FORMATS(" fdn_free_count: %d\n", fdn_free_count);
+ LOG_FORMATS(" volume_number: %d\n", volume_number);
+ LOG_FORMATS(" disk density: %02x, side info %02x\n", disk_density, disk_side_info);
+ LOG_FORMATS(" volbc_start_addr: %d\n", volbc_start_addr);
+ LOG_FORMATS(" swap_size: %d\n", swap_size);
+
+ // The first eight bytes appear to be zeros.
+ if (pick_integer_be(sir, 0x00, 8) != 0)
+ return -1;
+
+ for(int i=0; formats[i].form_factor; i++) {
+ const format &f = formats[i];
+ if(form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
+ continue;
+
+ if(size != (uint64_t)compute_track_size(f) * f.track_count * f.head_count)
+ continue;
+
+ // Check consistency with the SIR sector.
+ if(last_block_number + 1 + swap_size != f.sector_count * f.track_count * f.head_count)
+ continue;
+ if(f.head_count == 2 && disk_side_info == 0)
+ continue;
+ if(f.encoding == floppy_image::MFM && disk_density == 0)
+ continue;
+ if(f.encoding == floppy_image::FM && disk_density != 0)
+ continue;
+
+ return i;
+ }
+ return -1;
+}
+
+// UniFLEX numbers sectors on the second side of a track continuing from the
+// first side which is a variation not handled by the generic code.
+void uniflex_format::build_sector_description(const format &f, uint8_t *sectdata, desc_s *sectors, int track, int head) const
+{
+ if(f.sector_base_id == -1) {
+ for(int i=0; i<f.sector_count; i++) {
+ int cur_offset = 0;
+ for(int j=0; j<f.sector_count; j++)
+ if(f.per_sector_id[j] < f.per_sector_id[i])
+ cur_offset += f.sector_base_size ? f.sector_base_size : f.per_sector_size[j];
+ sectors[i].data = sectdata + cur_offset;
+ sectors[i].size = f.sector_base_size ? f.sector_base_size : f.per_sector_size[i];
+ sectors[i].sector_id = f.sector_count * head + f.per_sector_id[i];
+ }
+ } else {
+ int cur_offset = 0;
+ for(int i=0; i<f.sector_count; i++) {
+ sectors[i].data = sectdata + cur_offset;
+ sectors[i].size = f.sector_base_size ? f.sector_base_size : f.per_sector_size[i];
+ cur_offset += sectors[i].size;
+ sectors[i].sector_id = f.sector_count * head + i + f.sector_base_id;
+ }
+ }
+}
+
+const uniflex_format::format uniflex_format::formats[] = {
+ { // 616K 8 inch double density - gaps unverified
+ floppy_image::FF_8, floppy_image::SSDD, floppy_image::MFM,
+ 1000, 16, 77, 1, 512, {}, 1, {}, 32, 22, 50
+ },
+ { // 1232K 8 inch double density - gaps unverified
+ floppy_image::FF_8, floppy_image::DSDD, floppy_image::MFM,
+ 1000, 16, 77, 2, 512, {}, 1, {}, 32, 22, 50
+ },
+
+ {}
+};
+
+const floppy_format_type FLOPPY_UNIFLEX_FORMAT = &floppy_image_format_creator<uniflex_format>;
diff --git a/src/lib/formats/uniflex_dsk.h b/src/lib/formats/uniflex_dsk.h
new file mode 100644
index 00000000000..cd3a3c515ab
--- /dev/null
+++ b/src/lib/formats/uniflex_dsk.h
@@ -0,0 +1,32 @@
+// license:BSD-3-Clause
+// copyright-holders:68bit
+/*
+ * uniflex_dsk.h
+ */
+#ifndef MAME_FORMATS_UNIFLEX_DSK_H
+#define MAME_FORMATS_UNIFLEX_DSK_H
+
+#pragma once
+
+#include "flopimg.h"
+#include "wd177x_dsk.h"
+
+class uniflex_format : public wd177x_format
+{
+public:
+ uniflex_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 int find_size(io_generic *io, uint32_t form_factor) override;
+ void build_sector_description(const format &f, uint8_t *sectdata, desc_s *sectors, int track, int head) const override;
+
+private:
+ static const format formats[];
+};
+
+extern const floppy_format_type FLOPPY_UNIFLEX_FORMAT;
+
+#endif // MAME_FORMATS_UNIFLEX_DSK_H
diff --git a/src/tools/floptool.cpp b/src/tools/floptool.cpp
index f07e6ec9ad2..1953e7b0538 100644
--- a/src/tools/floptool.cpp
+++ b/src/tools/floptool.cpp
@@ -55,6 +55,9 @@
#include "formats/aim_dsk.h"
#include "formats/m20_dsk.h"
+#include "formats/flex_dsk.h"
+#include "formats/uniflex_dsk.h"
+
static floppy_format_type floppy_formats[] = {
FLOPPY_MFI_FORMAT,
@@ -98,7 +101,10 @@ static floppy_format_type floppy_formats[] = {
FLOPPY_DVK_MX_FORMAT,
FLOPPY_AIM_FORMAT,
- FLOPPY_M20_FORMAT
+ FLOPPY_M20_FORMAT,
+
+ FLOPPY_FLEX_FORMAT,
+ FLOPPY_UNIFLEX_FORMAT
};
void CLIB_DECL ATTR_PRINTF(1,2) logerror(const char *format, ...)