Exemple #1
0
 public Ssfs(Disk disk)
 {
     this.Disk = disk;
 }
Exemple #2
0
        private void addFileToDisk(Disk disk, string filename, ushort[] contents)
        {
            if (contents.Length > 0xffff)
                throw new SsfsException("file too long");

            // How many sectors do we need?
            var numsecs = (contents.Length + disk.SectorSize - 1) / disk.SectorSize;

            var startsec = 0;

            if (numsecs > 0)
            {
                // Find that many free sectors.
                var secs = new ushort[numsecs];
                {
                    var cur = disk.Words[5];
                    var sec = 0;
                    while (cur != 0 && sec < numsecs)
                    {
                        secs[sec++] = cur;
                        cur = disk.Sector[cur].Get(0);
                    }

                    if (sec != numsecs)
                        throw new SsfsException("not enough free sectors");
                }

                startsec = secs[0];

                // Write data to sectors.
                {
                    var coff = 0;
                    for (var s = 0; s < numsecs; ++s)
                    {
                        var sec = disk.Sector[secs[s]];
                        var stop = Math.Min(coff + 511, contents.Length);
                        for (var i = 1; coff < stop; ++i, ++coff)
                            sec.Set(i, contents[coff]);
                    }
                }

                // Unlink last sector, fix first free sector.
                disk.Words[5] = disk.Sector[secs[numsecs - 1]].Get(0);
                disk.Sector[secs[numsecs - 1]].Set(0, 0);
            }

            // Find a free directory entry.
            var dirent = -1;
            var dirstart = disk.Words[6] * disk.SectorSize;
            for (int i = 0; i < MaxDirEnts; ++i)
            {
                if (disk.Words[dirstart + 8 * i] == 0)
                {
                    dirent = i;
                    break;
                }
            }

            if (dirent < 0)
                throw new SsfsException("no free directory entries");

            // Write directory entry
            var direntoff = dirstart + dirent * 8;
            for (var i = 0; i < 6; ++i)
                disk.Words[direntoff + i] = 0;

            {
                var name = System.IO.Path.GetFileNameWithoutExtension(filename).ToUpper();
                var ext = System.IO.Path.GetExtension(filename).ToUpper();

                // Remove leading dot.
                if (ext.Length > 0) ext = ext.Substring(1);

                if (name.Length > 8)
                    throw new SsfsException("file name too long");
                if (ext.Length > 4)
                    throw new SsfsException("file extension too long");

                name.PackInto(disk.Words, direntoff);
                ext.PackInto(disk.Words, direntoff + 4);

                disk.Words[direntoff + 6] = (ushort)startsec;
                disk.Words[direntoff + 7] = (ushort)contents.Length;
            }
        }
Exemple #3
0
        private IEnumerable<FileEntry> iterDiskFiles(Disk disk)
        {
            var dirstart = disk.Words[6] * disk.SectorSize;
            var stop = dirstart + 512 * 8;
            for (var i = dirstart; i < stop; i += 8)
            {
                if (disk.Words[i] == 0)
                    break;
                else if (disk.Words[i] == 0xffff)
                    continue;

                var name = disk.Words.UnpackString(i, 4);
                var ext = disk.Words.UnpackString(i+4, 2);

                var path = name + (ext.Length > 0 ? "." + ext : "");

                yield return new FileEntry()
                {
                    Path = path,
                    StartSector = disk.Words[i+6],
                    Length = disk.Words[i+7],
                };
            }
        }
Exemple #4
0
 private List<FileEntry> listDiskFiles(Disk disk)
 {
     var l = new List<FileEntry>();
     foreach (var entry in iterDiskFiles(disk))
     {
         l.Add(entry);
     }
     return l;
 }
Exemple #5
0
 internal DiskSectors(Disk disk, int sectorWords)
     : this()
 {
     this.SectorSize = sectorWords;
     this.Disk = disk;
 }
Exemple #6
0
        private void formatDisk(Disk disk, ushort[] bootloader)
        {
            // How many sectors will the bootloader require?
            var bootsecs = 0;
            if (bootloader != null)
                bootsecs = (32 + bootloader.Length + disk.SectorSize - 1)
                    / disk.SectorSize;

            // Where will the directory listing go?
            var dirsec = bootsecs + 1;

            // Zero out the directory sectors.
            for (var i = 0; i < 8; ++i)
                disk.Sector[dirsec + i].Fill(0);

            // Link unused sectors together.
            var secs = disk.Sectors;
            for (var i = dirsec + 8; i < secs; ++i)
            {
                disk.Sector[i].Fill(0);
                if (i < secs - 1)
                    disk.Sector[i].Set(0, (ushort)(i + 1));
            }

            // Write header
            var header = disk.Sector[0];
            header.Set(0, 0);
            header.Set(1, 0);
            "SSFS".PackInto(header, 2);
            header.Set(4, 0x0100);
            header.Set(5, (ushort)(dirsec + 8));
            header.Set(6, (ushort)dirsec);

            // Write bootloader.
            if (bootloader != null)
            {
                header.Set(0, BootJump0);
                header.Set(1, BootJump1);
                bootloader.CopyTo(disk.Words, 32);
            }

            // Done!
        }
Exemple #7
0
 public void WriteTo(Stream s, bool raw = false)
 {
     Disk.WriteTo(s, raw);
 }
Exemple #8
0
 public void WriteTo(string path, bool raw = false)
 {
     Disk.WriteTo(path, raw);
 }
Exemple #9
0
 public Ssfs(Disk disk)
 {
     this.Disk = disk;
 }
Exemple #10
0
        private void addFileToDisk(Disk disk, string filename, ushort[] contents)
        {
            if (contents.Length > 0xffff)
            {
                throw new SsfsException("file too long");
            }

            // How many sectors do we need?
            var numsecs = (contents.Length + disk.SectorSize - 1) / disk.SectorSize;

            var startsec = 0;

            if (numsecs > 0)
            {
                // Find that many free sectors.
                var secs = new ushort[numsecs];
                {
                    var cur = disk.Words[5];
                    var sec = 0;
                    while (cur != 0 && sec < numsecs)
                    {
                        secs[sec++] = cur;
                        cur         = disk.Sector[cur].Get(0);
                    }

                    if (sec != numsecs)
                    {
                        throw new SsfsException("not enough free sectors");
                    }
                }

                startsec = secs[0];

                // Write data to sectors.
                {
                    var coff = 0;
                    for (var s = 0; s < numsecs; ++s)
                    {
                        var sec  = disk.Sector[secs[s]];
                        var stop = Math.Min(coff + 511, contents.Length);
                        for (var i = 1; coff < stop; ++i, ++coff)
                        {
                            sec.Set(i, contents[coff]);
                        }
                    }
                }

                // Unlink last sector, fix first free sector.
                disk.Words[5] = disk.Sector[secs[numsecs - 1]].Get(0);
                disk.Sector[secs[numsecs - 1]].Set(0, 0);
            }

            // Find a free directory entry.
            var dirent   = -1;
            var dirstart = disk.Words[6] * disk.SectorSize;

            for (int i = 0; i < MaxDirEnts; ++i)
            {
                if (disk.Words[dirstart + 8 * i] == 0)
                {
                    dirent = i;
                    break;
                }
            }

            if (dirent < 0)
            {
                throw new SsfsException("no free directory entries");
            }

            // Write directory entry
            var direntoff = dirstart + dirent * 8;

            for (var i = 0; i < 6; ++i)
            {
                disk.Words[direntoff + i] = 0;
            }

            {
                var name = System.IO.Path.GetFileNameWithoutExtension(filename).ToUpper();
                var ext  = System.IO.Path.GetExtension(filename).ToUpper();

                // Remove leading dot.
                if (ext.Length > 0)
                {
                    ext = ext.Substring(1);
                }

                if (name.Length > 8)
                {
                    throw new SsfsException("file name too long");
                }
                if (ext.Length > 4)
                {
                    throw new SsfsException("file extension too long");
                }

                name.PackInto(disk.Words, direntoff);
                ext.PackInto(disk.Words, direntoff + 4);

                disk.Words[direntoff + 6] = (ushort)startsec;
                disk.Words[direntoff + 7] = (ushort)contents.Length;
            }
        }
Exemple #11
0
        static void MainTest(string[] args)
        {
            {
                var disk = new Disk();
                "Hello, World!".PackInto(disk.Words, 0);
                disk.WriteTo("hello.disk.txt");
                disk.WriteTo("hello.disk.bin", raw: true);
            }

            int __break = 1;

            {
                var disk = new Disk("hello.disk.txt");
                var msg = disk.Words.UnpackString(0);
                Console.WriteLine("Message: \"{0}\"", msg);
            }

            {
                var disk = new Disk();
                disk.ReadFrom("hello.disk.bin", raw: true);
                var msg = disk.Words.UnpackString(0);
                Console.WriteLine("Message: \"{0}\"", msg);
            }

            {
                var fs = new Ssfs();

                fs.Format(BinaryImage.ReadImage("boot/bootload.bin"));
                fs.AddFile("kernel.sys", BinaryImage.ReadImage("boot/kernel.sys"));
                fs.AddFile("hmd2043.drv", BinaryImage.ReadImage("boot/hmd2043.drv"));
                fs.AddFile("ssfs.drv", BinaryImage.ReadImage("boot/ssfs.drv"));
                fs.AddFile("shell.sys", BinaryImage.ReadImage("boot/shell.sys"));
                fs.AddFile("shell.ro", BinaryImage.ReadImage("boot/shell.ro"));

                fs.WriteTo("boot.disk.txt");
                fs.WriteTo("boot.disk.bin", raw: true);
            }

            {
                var fs = new Ssfs("boot.disk.txt");
                Console.WriteLine("List of files in boot.disk.txt:");
                foreach (var file in fs.IterFiles())
                    Console.WriteLine(" {0}", file.Path);
            }
        }