dmolony-DiskBrowser/src/com/bytezone/diskbrowser/cpm/CPMDisk.java
Denis Molony 37b0f587e7 colours!
2016-02-25 13:49:12 +11:00

154 lines
4.5 KiB
Java

package com.bytezone.diskbrowser.cpm;
import java.awt.Color;
import java.util.List;
import javax.swing.tree.DefaultMutableTreeNode;
import com.bytezone.diskbrowser.applefile.AppleFileSource;
import com.bytezone.diskbrowser.applefile.BootSector;
import com.bytezone.diskbrowser.disk.*;
public class CPMDisk extends AbstractFormattedDisk
{
private final Color green = new Color (0, 200, 0);
public final SectorType catalogSector = new SectorType ("Catalog", green);
public final SectorType cpmSector = new SectorType ("CPM", Color.lightGray);
public final SectorType comSector = new SectorType ("COM", Color.red);
public final SectorType dataSector = new SectorType ("Data", Color.blue);
public final SectorType docSector = new SectorType ("DOC", Color.cyan);
public final SectorType xxxSector = new SectorType ("xxx", Color.gray);
private int version; // http://www.seasip.info/Cpm/format22.html
public CPMDisk (Disk disk)
{
super (disk);
sectorTypesList.add (catalogSector);
sectorTypesList.add (cpmSector);
sectorTypesList.add (comSector);
sectorTypesList.add (dataSector);
sectorTypesList.add (xxxSector);
sectorTypesList.add (docSector);
byte[] sectorBuffer = disk.readSector (0, 0); // Boot sector
bootSector = new BootSector (disk, sectorBuffer, "CPM");
sectorTypes[0] = cpmSector;
byte[] buffer = disk.readSector (0, 8);
String text = new String (buffer, 16, 24);
if ("DIR ERA TYPESAVEREN USER".equals (text))
version = buffer[41] & 0xFF;
DefaultMutableTreeNode root = getCatalogTreeRoot ();
for (int sector = 0; sector < 8; sector++)
{
DiskAddress da = disk.getDiskAddress (3, sector);
sectorTypes[da.getBlock ()] = catalogSector;
buffer = disk.readSector (da);
for (int i = 0; i < buffer.length; i += 32)
{
if (buffer[i] != 0 && buffer[i] != (byte) 0xE5)
break;
if (buffer[i] == 0)
{
DirectoryEntry entry = new DirectoryEntry (this, buffer, i);
SectorType sectorType = getSectorType (entry.getType ());
for (DiskAddress block : entry.getSectors ())
sectorTypes[block.getBlock ()] = sectorType;
DirectoryEntry parent = findParent (entry);
if (parent == null)
{
fileEntries.add (entry);
DefaultMutableTreeNode node = new DefaultMutableTreeNode (entry);
root.add (node);
node.setAllowsChildren (false);
}
else
parent.add (entry);
}
}
}
root.setUserObject (getCatalog ());
makeNodeVisible (root.getFirstLeaf ());
}
private SectorType getSectorType (String type)
{
if ("COM".equals (type))
return comSector;
if ("DOC".equals (type))
return docSector;
return dataSector;
}
@Override
public List<DiskAddress> getFileSectors (int fileNo)
{
return null;
}
private DirectoryEntry findParent (DirectoryEntry child)
{
for (AppleFileSource entry : fileEntries)
if (((DirectoryEntry) entry).matches (child))
return (DirectoryEntry) entry;
return null;
}
@Override
public AppleFileSource getCatalog ()
{
String newLine = String.format ("%n");
String line = "---- --------- ---- ---- ---- ----------------------------"
+ "-------------------" + newLine;
StringBuilder text = new StringBuilder ();
text.append (String.format ("Disk : %s%n%n", getAbsolutePath ()));
text.append ("User Name Type Exts Size Blocks" + newLine);
text.append (line);
for (AppleFileSource entry : fileEntries)
{
text.append (((DirectoryEntry) entry).line ());
text.append (newLine);
}
text.append (line);
return new DefaultAppleFileSource ("CPM Disk ", text.toString (), this);
}
public static boolean isCorrectFormat (AppleDisk disk)
{
disk.setInterleave (3);
byte[] buffer = disk.readSector (0, 8);
String text = new String (buffer, 16, 24);
if ("DIR ERA TYPESAVEREN USER".equals (text))
return true;
buffer = disk.readSector (0, 4);
text = new String (buffer, 16, 24);
if ("DIR ERA TYPESAVEREN USER".equals (text))
return true;
for (int sector = 0; sector < 8; sector++)
{
buffer = disk.readSector (3, sector);
for (int i = 0; i < buffer.length; i += 32)
{
int val = buffer[i] & 0xFF;
if (val > 31 && val != 0xE5)
return false;
}
}
return true;
}
}