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

137 lines
4.6 KiB
Java
Executable File

package com.bytezone.diskbrowser.prodos;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.applefile.ProdosDirectory;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
public class VolumeDirectoryHeader extends DirectoryHeader
// -----------------------------------------------------------------------------------//
{
protected final int bitMapBlock;
protected int totalBlocks;
protected int freeBlocks;
protected int usedBlocks;
protected int totalBitMapBlocks;
// ---------------------------------------------------------------------------------//
VolumeDirectoryHeader (ProdosDisk parentDisk, byte[] entryBuffer)
// ---------------------------------------------------------------------------------//
{
super (parentDisk, entryBuffer, 2, 1);
bitMapBlock = Utility.getShort (entryBuffer, 35);
totalBlocks = Utility.getShort (entryBuffer, 37);
totalBitMapBlocks = (totalBlocks - 1) / BLOCK_SIZE + 1;
int block = 2;
do
{
dataBlocks.add (disk.getDiskAddress (block));
byte[] buffer = disk.readBlock (block);
block = Utility.getShort (buffer, 2);
} while (block > 0);
// convert the Free Sector Table
int bitMapBytes = (totalBlocks - 1) / 8 + 1; // one bit per block
byte[] buffer = new byte[bitMapBytes];
int bitMapBlocks = (bitMapBytes - 1) / disk.getBlocksPerTrack () + 1;
int lastBitMapBlock = bitMapBlock + bitMapBlocks - 1;
int ptr = 0;
for (block = bitMapBlock; block <= lastBitMapBlock; block++)
{
byte[] temp = disk.readBlock (block);
int bytesToCopy = buffer.length - ptr;
if (bytesToCopy > temp.length)
bytesToCopy = temp.length;
System.arraycopy (temp, 0, buffer, ptr, bytesToCopy);
ptr += bytesToCopy;
}
// 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
// int max2 = (disk.getTotalBlocks () - 1) / 8 + 1; // bytes required for sector map
int max = (Math.min (totalBlocks, disk.getTotalBlocks ()) - 1) / 8 + 1;
block = 0;
for (int i = 0; i < max; i++)
{
byte b = buffer[i];
for (int j = 0; j < 8; j++)
{
boolean free = (b & 0x80) != 0;
if (free)
freeBlocks++;
parentDisk.setSectorFree (block++, free);
b <<= 1;
}
}
usedBlocks = totalBlocks - freeBlocks; // totalBlocks may not be a multiple of 8
}
// ---------------------------------------------------------------------------------//
@Override
public DataSource getDataSource ()
// ---------------------------------------------------------------------------------//
{
List<byte[]> blockList = new ArrayList<> ();
int block = 2;
do
{
byte[] buf = disk.readBlock (block);
blockList.add (buf);
block = Utility.getShort (buf, 2); // 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,
usedBlocks);
}
// ---------------------------------------------------------------------------------//
@Override
public List<DiskAddress> getSectors ()
// ---------------------------------------------------------------------------------//
{
List<DiskAddress> sectors = new ArrayList<> ();
sectors.addAll (dataBlocks);
return sectors;
}
// ---------------------------------------------------------------------------------//
@Override
public String getText ()
// ---------------------------------------------------------------------------------//
{
return String.format ("%s %04X %02X", super.getText (), totalBlocks, bitMapBlock);
}
// ---------------------------------------------------------------------------------//
@Override
public String toString ()
// ---------------------------------------------------------------------------------//
{
if (false)
{
String locked = (access == 0x01) ? "*" : " ";
String timeC = created == null ? "" : created.format (ProdosDisk.df);
return String.format (" %s%-42s %15s", locked, "/" + name, timeC);
}
return name;
}
}