dmolony-DiskBrowser/src/com/bytezone/diskbrowser/prodos/VolumeDirectoryHeader.java

133 lines
4.1 KiB
Java
Raw Normal View History

2015-06-01 09:35:51 +00:00
package com.bytezone.diskbrowser.prodos;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.gui.DataSource;
2016-02-24 21:11:14 +00:00
import com.bytezone.diskbrowser.utilities.HexFormatter;
2015-06-01 09:35:51 +00:00
/*
* There is only one of these - it is always the first entry in the first block.
* Every other entry will be either a SubDirectoryHeader or a FileEntry.
*/
class VolumeDirectoryHeader extends DirectoryHeader
{
2016-02-28 07:17:58 +00:00
protected final int bitMapBlock;
protected int totalBlocks;
protected int freeBlocks;
protected int usedBlocks;
protected int totalBitMapBlocks;
2015-06-01 09:35:51 +00:00
public VolumeDirectoryHeader (ProdosDisk parentDisk, byte[] entryBuffer)
{
super (parentDisk, entryBuffer);
2017-04-22 06:31:25 +00:00
bitMapBlock = HexFormatter.unsignedShort (entryBuffer, 35);
totalBlocks = HexFormatter.unsignedShort (entryBuffer, 37);
2017-05-08 01:46:28 +00:00
// if (totalBlocks == 0xFFFF || totalBlocks == 0x7FFF)
// totalBlocks = (int) disk.getFile ().length () / 4096 * 8;// ignore extra bytes
2015-06-01 09:35:51 +00:00
totalBitMapBlocks = (totalBlocks - 1) / 512 + 1;
int block = 2;
do
{
dataBlocks.add (disk.getDiskAddress (block));
byte[] buffer = disk.readSector (block);
2017-04-22 06:31:25 +00:00
block = HexFormatter.unsignedShort (buffer, 2);
2015-06-01 09:35:51 +00:00
} while (block > 0);
// convert the Free Sector Table
2018-07-23 07:39:25 +00:00
// int bitMapBytes = totalBlocks / 8; // one bit per block
int bitMapBytes = (totalBlocks - 1) / 8 + 1; // one bit per block
2015-06-01 09:35:51 +00:00
byte[] buffer = new byte[bitMapBytes];
int bitMapBlocks = (bitMapBytes - 1) / disk.getSectorsPerTrack () + 1;
int lastBitMapBlock = bitMapBlock + bitMapBlocks - 1;
int ptr = 0;
for (block = bitMapBlock; block <= lastBitMapBlock; block++)
{
byte[] temp = disk.readSector (block);
int bytesToCopy = buffer.length - ptr;
if (bytesToCopy > temp.length)
bytesToCopy = temp.length;
System.arraycopy (temp, 0, buffer, ptr, bytesToCopy);
ptr += bytesToCopy;
}
block = 0;
2016-02-28 05:41:30 +00:00
2016-02-28 07:17:58 +00:00
// nb1 dual-dos disk needs to use totalBlocks obtained from disk
// int max1 = (totalBlocks - 1) / 8 + 1; // bytes required for sector map
// nb2 hard disk may be truncated, so use actual number of blocks
2016-02-28 05:41:30 +00:00
// int max2 = (disk.getTotalBlocks () - 1) / 8 + 1; // bytes required for sector map
int max = (Math.min (totalBlocks, disk.getTotalBlocks ()) - 1) / 8 + 1;
2017-05-08 01:46:28 +00:00
// System.out.printf ("total blocks %,d%n", totalBlocks);
// System.out.printf ("disk blocks %,d%n", disk.getTotalBlocks ());
2015-06-01 09:35:51 +00:00
for (int i = 0; i < max; i++)
{
byte b = buffer[i];
for (int j = 0; j < 8; j++)
{
if ((b & 0x80) == 0x80)
{
freeBlocks++;
parentDisk.setSectorFree (block++, true);
}
else
{
usedBlocks++;
parentDisk.setSectorFree (block++, false);
}
b <<= 1;
}
}
}
@Override
public DataSource getDataSource ()
{
List<byte[]> blockList = new ArrayList<byte[]> ();
int block = 2;
do
{
byte[] buf = disk.readSector (block);
blockList.add (buf);
block = HexFormatter.intValue (buf[2], buf[3]); // next block
} while (block > 0);
byte[] fullBuffer = new byte[blockList.size () * 507];
int offset = 0;
for (byte[] bfr : blockList)
{
System.arraycopy (bfr, 4, fullBuffer, offset, 507);
offset += 507;
}
return new ProdosDirectory (parentDisk, name, fullBuffer, totalBlocks, freeBlocks,
2016-02-24 02:13:52 +00:00
usedBlocks);
2015-06-01 09:35:51 +00:00
}
@Override
public List<DiskAddress> getSectors ()
{
List<DiskAddress> sectors = new ArrayList<DiskAddress> ();
sectors.addAll (dataBlocks);
return sectors;
}
@Override
public String toString ()
{
if (false)
{
String locked = (access == 0x01) ? "*" : " ";
2016-03-24 00:17:09 +00:00
String timeC = created == null ? "" : parentDisk.df.format (created.getTime ());
2015-06-01 09:35:51 +00:00
return String.format (" %s%-42s %15s", locked, "/" + name, timeC);
}
return name;
}
}