public Ssfs(Disk disk) { this.Disk = disk; }
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; } }
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], }; } }
private List<FileEntry> listDiskFiles(Disk disk) { var l = new List<FileEntry>(); foreach (var entry in iterDiskFiles(disk)) { l.Add(entry); } return l; }
internal DiskSectors(Disk disk, int sectorWords) : this() { this.SectorSize = sectorWords; this.Disk = disk; }
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! }
public void WriteTo(Stream s, bool raw = false) { Disk.WriteTo(s, raw); }
public void WriteTo(string path, bool raw = false) { Disk.WriteTo(path, raw); }
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; } }
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); } }