/// <summary> /// Saves BAM data to disk image /// </summary> /// <param name="disk">Disk image to write</param> public override void Save(BaseDisk disk) { byte[] data = BaseDisk.EmptySector(); data[0] = Directory.Track; data[1] = Directory.Sector; data[2] = (byte)DOSversion; data[0x14] = 0xA0; data[0x15] = 0xA0; data[0x16] = (byte)DiskId[0]; data[0x17] = (byte)DiskId[1]; data[0x18] = 0xA0; data[0x19] = (byte)DOStype[0]; data[0x1A] = (byte)DOStype[1]; data[0x1B] = 0xA0; data[0x1C] = 0xA0; Array.Copy(DiskLabel(), 0, data, 4, 16); disk.PutSector(Directory.Track, 0, data); data = BAMsectorHeader(); data[0] = Directory.Track; data[1] = 2; Array.Copy(RawMap(41, 80), 0, data, 16, 40 * EntrySize); disk.PutSector(Directory.Track, 1, data); data = BAMsectorHeader(); data[0] = 0; data[1] = 0xFF; Array.Copy(RawMap(1, 40), 0, data, 16, 40 * EntrySize); disk.PutSector(Directory.Track, 2, data); }
/// <summary> /// Load BAM data from disk image /// </summary> /// <param name="disk">Disk image to read</param> public override void Load(BaseDisk disk) { LoadHeader(disk, 18, 0); const int tracks = 35; byte[] data = disk.GetSector(18, 0); DoubleSide = (data[3] == 0x80); byte[] table = new byte[tracks * 4]; Array.Copy(data, 4, table, 0, tracks * 4); SectorsMap.Clear(); loadMap(table, 4); for (int j = 0; j < tracks; j++) { table[j * 4] = data[0xDD + j]; } data = disk.GetSector(53, 0); for (int j = 0; j < tracks; j++) { Array.Copy(data, j * 3, table, j * 4, 3); } loadMap(table, 4); }
/// <summary> /// Load BAM data from disk image /// </summary> /// <param name="disk">Disk image to read</param> public override void Load(BaseDisk disk) { LoadHeader(disk, 39, 0); SectorsMap.Clear(); loadPartialBAM(disk, BAMtrack, 0); loadPartialBAM(disk, BAMtrack, 3); }
/// <summary> /// Read disk header /// </summary> /// <param name="disk">disk to analyze</param> /// <param name="track">header track</param> /// <param name="sector">header sector</param> protected override void LoadHeader(BaseDisk disk, int track, int sector) { base.LoadHeader(disk, track, sector); byte[] data = disk.GetSector(track, sector); DOStype[0] = (char)data[0xA5]; DOStype[1] = (char)data[0xA6]; }
/// <summary> /// Saves BAM data to disk image /// </summary> /// <param name="disk">Disk image to write</param> public override void Save(BaseDisk disk) { byte[] data = BaseHeader(); Array.Copy(RawMap(), 0, data, 4, totalTracks * EntrySize); disk.PutSector(18, 0, data); }
/// <summary> /// Single bam sector /// </summary> /// <param name="firstTrack"></param> /// <param name="lastTrack"></param> /// <returns></returns> protected byte[] BAMsector(byte firstTrack, byte lastTrack) { byte[] data = BaseDisk.EmptySector(); data[2] = (byte)DOSversion; data[4] = firstTrack; data[5] = (byte)(lastTrack + 1); Array.Copy(RawMap(firstTrack, lastTrack), 0, data, 6, (lastTrack - firstTrack + 1) * EntrySize); return(data); }
/// <summary> /// Loads BAM data from disk image /// </summary> /// <param name="disk">Disk image to read</param> public override void Load(BaseDisk disk) { LoadHeader(disk, 18, 0); byte[] data = disk.GetSector(18, 0); byte[] table = new byte[totalTracks * 4]; Array.Copy(data, 4, table, 0, totalTracks * 4); SectorsMap.Clear(); loadMap(table, 4); }
/// <summary> /// Load partial BAM /// </summary> /// <param name="disk">Disk to read</param> /// <param name="track">BAM track</param> /// <param name="sector">BAM sector</param> protected void loadPartialBAM(BaseDisk disk, int track, int sector) { byte[] data = disk.GetSector(track, sector); int firstTrack = data[4]; int lastTrack = data[5]; int tracks = lastTrack - firstTrack; byte[] table = new byte[tracks * 5]; Array.Copy(data, 6, table, 0, tracks * 5); loadMap(table, 5); }
private byte[] BAMsectorHeader() { byte[] data = BaseDisk.EmptySector(); data[2] = (byte)DOSversion; data[3] = (byte)~DOSversion; data[4] = (byte)DiskId[0]; data[5] = (byte)DiskId[1]; data[6] = 0; // No checks data[7] = 0; // No autorun return(data); }
/// <summary> /// Saves BAM data to disk image /// </summary> /// <param name="disk">Disk image to write</param> public override void Save(BaseDisk disk) { SaveHeader(disk); byte[] data = BAMsector(1, 50); data[0] = BAMtrack; data[1] = 3; disk.PutSector(BAMtrack, 0, data); data = BAMsector(51, 77); data[0] = Directory.Track; data[1] = Directory.Sector; disk.PutSector(BAMtrack, 3, data); }
/// <summary> /// Load BAM data from disk image /// </summary> /// <param name="disk">Disk image to read</param> public override void Load(BaseDisk disk) { LoadHeader(disk, 40, 0); const int tracks = 40; byte[] table = new byte[tracks * 6]; byte[] data = disk.GetSector(40, 1); Array.Copy(data, 0x10, table, 0, tracks * 6); SectorsMap.Clear(); loadMap(table, 6); data = disk.GetSector(40, 2); Array.Copy(data, 0x10, table, 0, tracks * 6); loadMap(table, 6); }
/// <summary> /// Load header from disk image /// </summary> /// <param name="disk">Disk image to read</param> /// <param name="track">Track of disk header</param> /// <param name="sector">Secton inside track of disk header</param> protected virtual void LoadHeader(BaseDisk disk, int track, int sector) { byte[] data = disk.GetSector(track, sector); Directory = new SectorId(data[0], data[1]); DOSversion = (char)data[2]; DiskName = string.Empty; for (int j = 0x90; j <= 0x9F; j++) { DiskName += (char)data[j]; } DiskId[0] = (char)data[0xA2]; DiskId[1] = (char)data[0xA3]; DOStype[0] = (char)data[0xA5]; DOStype[1] = (char)data[0xA6]; }
/// <summary> /// Read disk header /// </summary> /// <param name="disk">disk to analyze</param> /// <param name="track">header track</param> /// <param name="sector">header sector</param> protected override void LoadHeader(BaseDisk disk, int track, int sector) { byte[] data = disk.GetSector(track, sector); BAM = new SectorId(data[0], data[1]); Directory = new SectorId(39, 1); DOSversion = (char)data[2]; DiskName = string.Empty; for (int j = 0x06; j <= 0x16; j++) { DiskName += (char)data[j]; } DiskId[0] = (char)data[0x18]; DiskId[1] = (char)data[0x19]; DOStype[0] = (char)data[0x1B]; DOStype[1] = (char)data[0x1C]; }
/// <summary> /// Saves BAM data to disk image /// </summary> /// <param name="disk">Disk image to write</param> public override void Save(BaseDisk disk) { byte[] data = BaseHeader(); Array.Copy(RawMap(), 0, data, 4, 35 * EntrySize); for (int j = 0; j < 35; ++j) { data[0xDD + j] = SectorsMap[35 + j].FreeSectors; } disk.PutSector(18, 0, data); data = BaseDisk.EmptySector(); for (int j = 0; j < 35; ++j) { Array.Copy(SectorsMap[35 + j].flags, 0, data, j * 3, 3); } disk.PutSector(53, 0, data); }
/// <summary> /// Loads directory from disk image database /// </summary> /// <param name="disk">disk image to read</param> /// <param name="id">directory start track/sector</param> public void Load(BaseDisk disk, SectorId id) { byte[] sectorData = disk.GetSector(id); for (byte j = 0; j < EntriesPerSector; j++) { byte[] entryData = new byte[DirectoryEntry.EntrySize]; Array.Copy(sectorData, j * DirectoryEntry.EntrySize, entryData, 0, DirectoryEntry.EntrySize); addEntry(entryData, id, j); } if (sectorData[0] == 0) { return; } Load(disk, new SectorId(sectorData[0], sectorData[1])); }
/// <summary> /// Directory as a list of raw sector data /// </summary> /// <returns></returns> public List <byte[]> ToRaw() { List <byte[]> ret = new List <byte[]>(); int sectors = (dir.Count + EntriesPerSector - 1) / EntriesPerSector; // see https://stackoverflow.com/questions/17944/how-to-round-up-the-result-of-integer-division for (int j = 0; j < sectors; j++) { byte[] s = BaseDisk.EmptySector(); for (int e = 0; e < EntriesPerSector && j * EntriesPerSector + e < dir.Count; ++e) { Array.Copy(dir[j * EntriesPerSector + e].ToRaw(), 0, s, e * DirectoryEntry.EntrySize, DirectoryEntry.EntrySize); } } return(ret); }
/// <summary> /// Writes disk header /// </summary> /// <param name="disk"></param> protected void SaveHeader(BaseDisk disk) { byte[] data = BaseDisk.EmptySector(); data[0] = BAMtrack; data[1] = 0; data[2] = (byte)DOSversion; data[0x17] = 0xA0; data[0x18] = (byte)DiskId[0]; data[0x19] = (byte)DiskId[1]; data[0x1A] = 0xA0; data[0x1B] = (byte)DOStype[0]; data[0x1C] = (byte)DOStype[1]; data[0x1D] = 0xA0; data[0x1E] = 0xA0; data[0x1F] = 0xA0; data[0x20] = 0xA0; Array.Copy(DiskLabel(), 0, data, 6, 16); disk.PutSector(Directory.Track, 0, data); }
/// <summary> /// Disk Header /// </summary> /// <returns></returns> protected virtual byte[] BaseHeader() { byte[] data = BaseDisk.EmptySector(); data[0] = Directory.Track; data[1] = Directory.Sector; data[2] = (byte)DOSversion; data[3] = (byte)(DoubleSide ? 0x80 : 0); data[0xA0] = 0xA0; data[0xA1] = 0xA0; data[0xA2] = (byte)DiskId[0]; data[0xA3] = (byte)DiskId[1]; data[0xA4] = 0xA0; data[0xA5] = (byte)DOStype[0]; data[0xA6] = (byte)DOStype[1]; data[0xA7] = 0xA0; data[0xA8] = 0xA0; data[0xA9] = 0xA0; data[0xAA] = 0xA0; Array.Copy(DiskLabel(), 0, data, 0x90, 16); return(data); }
/// <summary> /// Puts directory in disk sectors /// </summary> /// <param name="disk"></param> public void Save(BaseDisk disk) { disk.Header.FreeSectorsOnDirectoryTrack(); List <byte[]> rawData = ToRaw(); byte prevSect = disk.Header.Directory.Sector; if (rawData.Count > 0) { disk.PutSector(disk.Header.Directory.Track, prevSect, rawData[0]); for (int j = 1; j < rawData.Count; ++j) { int sect = disk.Header.GetAFreeSector(disk.Header.Directory.Track); if (sect > 0) { disk.GetSector(disk.Header.Directory.Track, prevSect)[0] = disk.Header.Directory.Track; disk.GetSector(disk.Header.Directory.Track, prevSect)[0] = (byte)sect; prevSect = (byte)sect; disk.PutSector(disk.Header.Directory.Track, sect, rawData[j]); } } } }
/// <summary> /// Loads directory from disk image database using standard parameters /// </summary> /// <param name="disk">disk image to read</param> public void Load(BaseDisk disk) { Load(disk, First); }
/// <summary> /// Load BAM data from disk image /// </summary> /// <param name="disk">Disk image to read</param> /// <remarks>Empty virtual method</remarks> public virtual void Load(BaseDisk disk) { }
/// <summary> /// Saves BAM data to disk image /// </summary> /// <param name="disk">Disk image to write</param> /// <remarks>Empty virtual method</remarks> public virtual void Save(BaseDisk disk) { }