diff --git a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj
index 096338e06..e78dcfa91 100644
--- a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj
+++ b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj
@@ -136,6 +136,7 @@
+
@@ -193,7 +194,7 @@
-
+
diff --git a/DiscImageChef.Filesystems/MicroDOS.cs b/DiscImageChef.Filesystems/MicroDOS.cs
new file mode 100644
index 000000000..37452ff43
--- /dev/null
+++ b/DiscImageChef.Filesystems/MicroDOS.cs
@@ -0,0 +1,238 @@
+// /***************************************************************************
+// The Disc Image Chef
+// ----------------------------------------------------------------------------
+//
+// Filename : MicroDOS.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Component
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Description
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2017 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using DiscImageChef.CommonTypes;
+
+namespace DiscImageChef.Filesystems
+{
+ // Information from http://www.owg.ru/mkt/BK/MKDOS.TXT
+ // Thanks to tarlabnor for translating it
+ public class MicroDOS : Filesystem
+ {
+ const ushort magic = 0xA72E;
+ const ushort magic2 = 0x530C;
+
+ public MicroDOS()
+ {
+ Name = "MicroDOS file system";
+ PluginUUID = new Guid("9F9A364A-1A27-48A3-B730-7A7122000324");
+ CurrentEncoding = Encoding.GetEncoding("koi8-r");
+ }
+
+ public MicroDOS(ImagePlugins.ImagePlugin imagePlugin, Partition partition, Encoding encoding)
+ {
+ Name = "MicroDOS file system";
+ PluginUUID = new Guid("9F9A364A-1A27-48A3-B730-7A7122000324");
+ if(encoding == null)
+ CurrentEncoding = Encoding.GetEncoding("koi8-r");
+ else
+ CurrentEncoding = encoding;
+ }
+
+ public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, Partition partition)
+ {
+ if((1 + partition.Start) >= partition.End)
+ return false;
+
+ if(imagePlugin.GetSectorSize() < 512)
+ return false;
+
+ MicroDOSBlock0 block0 = new MicroDOSBlock0();
+
+ byte[] bk0 = imagePlugin.ReadSector(0 + partition.Start);
+
+ GCHandle handle = GCHandle.Alloc(bk0, GCHandleType.Pinned);
+ block0 = (MicroDOSBlock0)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MicroDOSBlock0));
+ handle.Free();
+
+ return block0.label == magic && block0.mklabel == magic2;
+ }
+
+ public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, Partition partition, out string information)
+ {
+ information = "";
+
+ StringBuilder sb = new StringBuilder();
+ MicroDOSBlock0 block0 = new MicroDOSBlock0();
+
+ byte[] bk0 = imagePlugin.ReadSector(0 + partition.Start);
+
+ GCHandle handle = GCHandle.Alloc(bk0, GCHandleType.Pinned);
+ block0 = (MicroDOSBlock0)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MicroDOSBlock0));
+ handle.Free();
+
+ sb.AppendLine("MicroDOS filesystem");
+ sb.AppendFormat("Volume has {0} blocks ({1} bytes)", block0.blocks, block0.blocks * 512).AppendLine();
+ sb.AppendFormat("Volume has {0} blocks used ({1} bytes)", block0.usedBlocks, block0.usedBlocks * 512).AppendLine();
+ sb.AppendFormat("Volume contains {0} files", block0.files).AppendLine();
+ sb.AppendFormat("First used block is {0}", block0.firstUsedBlock).AppendLine();
+
+ xmlFSType = new Schemas.FileSystemType
+ {
+ Type = "MicroDOS",
+ ClusterSize = 512,
+ Clusters = block0.blocks,
+ Files = block0.files,
+ FilesSpecified = true,
+ FreeClusters = block0.blocks - block0.usedBlocks,
+ FreeClustersSpecified = true
+ };
+
+ information = sb.ToString();
+ }
+
+ // Followed by directory entries
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct MicroDOSBlock0
+ {
+ /// BK starts booting here
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
+ public byte[] bootCode;
+ /// Number of files in directory
+ public ushort files;
+ /// Total number of blocks in files of the directory
+ public ushort usedBlocks;
+ /// Unknown
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 228)]
+ public byte[] unknown;
+ /// Ownership label (label that shows it belongs to Micro DOS format)
+ public ushort label;
+ /// MK-DOS directory format label
+ public ushort mklabel;
+ /// Unknown
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
+ public byte[] unknown2;
+ /// Disk size in blocks (absolute value for the system unlike NORD, NORTON etc.) that
+ /// doesn't use two fixed values 40 or 80 tracks, but i.e. if you drive works with 76 tracks
+ /// this field will contain an appropriate number of blocks
+ public ushort blocks;
+ /// Number of the first file's block. Value is changable
+ public ushort firstUsedBlock;
+ /// Unknown
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
+ public byte[] unknown3;
+ }
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct DirectoryEntry
+ {
+ /// File status
+ public byte status;
+ /// Directory number (0 - root)
+ public byte directory;
+ /// File name 14. symbols in ASCII KOI8
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
+ public byte[] filename;
+ /// Block number
+ public ushort blockNo;
+ /// Length in blocks
+ public ushort blocks;
+ /// Address
+ public ushort address;
+ /// Length
+ public ushort length;
+ }
+
+ enum FileStatus : byte
+ {
+ CommonFile = 0,
+ Protected = 1,
+ LogicalDisk = 2,
+ BadFile = 0x80,
+ Deleted = 0xFF
+ }
+
+ public override Errno Mount()
+ {
+ return Errno.NotImplemented;
+ }
+
+ public override Errno Mount(bool debug)
+ {
+ return Errno.NotImplemented;
+ }
+
+ public override Errno Unmount()
+ {
+ return Errno.NotImplemented;
+ }
+
+ public override Errno MapBlock(string path, long fileBlock, ref long deviceBlock)
+ {
+ return Errno.NotImplemented;
+ }
+
+ public override Errno GetAttributes(string path, ref FileAttributes attributes)
+ {
+ return Errno.NotImplemented;
+ }
+
+ public override Errno ListXAttr(string path, ref List xattrs)
+ {
+ return Errno.NotImplemented;
+ }
+
+ public override Errno GetXattr(string path, string xattr, ref byte[] buf)
+ {
+ return Errno.NotImplemented;
+ }
+
+ public override Errno Read(string path, long offset, long size, ref byte[] buf)
+ {
+ return Errno.NotImplemented;
+ }
+
+ public override Errno ReadDir(string path, ref List contents)
+ {
+ return Errno.NotImplemented;
+ }
+
+ public override Errno StatFs(ref FileSystemInfo stat)
+ {
+ return Errno.NotImplemented;
+ }
+
+ public override Errno Stat(string path, ref FileEntryInfo stat)
+ {
+ return Errno.NotImplemented;
+ }
+
+ public override Errno ReadLink(string path, ref string dest)
+ {
+ return Errno.NotImplemented;
+ }
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 63911e104..297d9bcae 100644
--- a/README.md
+++ b/README.md
@@ -148,6 +148,7 @@ Supported file systems for identification and information only
* Linux extended file system 3
* Linux extended file system 4
* Locus file system
+* MicroDOS file system
* Microsoft 12-bit File Allocation Table (FAT12), including Atari ST extensions
* Microsoft 16-bit File Allocation Table (FAT16)
* Microsoft 32-bit File Allocation Table (FAT32), including FAT+ extension