2015-06-01 09:35:51 +00:00
|
|
|
package com.bytezone.diskbrowser.cpm;
|
|
|
|
|
|
|
|
import java.awt.Color;
|
|
|
|
import java.util.List;
|
|
|
|
|
2016-02-25 01:55:14 +00:00
|
|
|
import javax.swing.tree.DefaultMutableTreeNode;
|
|
|
|
|
2016-02-25 01:27:22 +00:00
|
|
|
import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
|
|
|
import com.bytezone.diskbrowser.disk.*;
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
public class CPMDisk extends AbstractFormattedDisk
|
|
|
|
{
|
|
|
|
private final Color green = new Color (0, 200, 0);
|
2016-02-25 07:45:24 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
public final SectorType catalogSector = new SectorType ("Catalog", green);
|
2016-02-25 07:45:24 +00:00
|
|
|
public final SectorType prnSector = new SectorType ("PRN", Color.lightGray);
|
2016-02-25 02:49:12 +00:00
|
|
|
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);
|
2016-02-25 07:45:24 +00:00
|
|
|
public final SectorType basSector = new SectorType ("BAS", Color.gray);
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-02-24 12:32:36 +00:00
|
|
|
private int version; // http://www.seasip.info/Cpm/format22.html
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
public CPMDisk (Disk disk)
|
|
|
|
{
|
|
|
|
super (disk);
|
2016-02-25 02:49:12 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
sectorTypesList.add (catalogSector);
|
2016-02-25 07:45:24 +00:00
|
|
|
sectorTypesList.add (prnSector);
|
2016-02-25 02:49:12 +00:00
|
|
|
sectorTypesList.add (comSector);
|
|
|
|
sectorTypesList.add (dataSector);
|
2016-02-25 07:45:24 +00:00
|
|
|
sectorTypesList.add (basSector);
|
2016-02-25 02:49:12 +00:00
|
|
|
sectorTypesList.add (docSector);
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-02-25 07:45:24 +00:00
|
|
|
getDisk ().setEmptyByte ((byte) 0xE5);
|
|
|
|
setSectorTypes ();
|
|
|
|
|
|
|
|
// byte[] sectorBuffer = disk.readSector (0, 0); // Boot sector
|
|
|
|
// bootSector = new BootSector (disk, sectorBuffer, "CPM");
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-02-24 12:32:36 +00:00
|
|
|
byte[] buffer = disk.readSector (0, 8);
|
|
|
|
String text = new String (buffer, 16, 24);
|
|
|
|
if ("DIR ERA TYPESAVEREN USER".equals (text))
|
|
|
|
version = buffer[41] & 0xFF;
|
|
|
|
|
2016-02-25 01:55:14 +00:00
|
|
|
DefaultMutableTreeNode root = getCatalogTreeRoot ();
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
for (int sector = 0; sector < 8; sector++)
|
|
|
|
{
|
|
|
|
DiskAddress da = disk.getDiskAddress (3, sector);
|
|
|
|
sectorTypes[da.getBlock ()] = catalogSector;
|
2016-02-24 21:27:03 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2016-02-25 01:55:14 +00:00
|
|
|
DirectoryEntry entry = new DirectoryEntry (this, buffer, i);
|
2016-02-25 02:49:12 +00:00
|
|
|
SectorType sectorType = getSectorType (entry.getType ());
|
|
|
|
for (DiskAddress block : entry.getSectors ())
|
|
|
|
sectorTypes[block.getBlock ()] = sectorType;
|
|
|
|
|
2016-02-24 21:27:03 +00:00
|
|
|
DirectoryEntry parent = findParent (entry);
|
|
|
|
if (parent == null)
|
2016-02-25 01:55:14 +00:00
|
|
|
{
|
|
|
|
fileEntries.add (entry);
|
|
|
|
DefaultMutableTreeNode node = new DefaultMutableTreeNode (entry);
|
|
|
|
root.add (node);
|
|
|
|
node.setAllowsChildren (false);
|
|
|
|
}
|
2016-02-24 21:27:03 +00:00
|
|
|
else
|
|
|
|
parent.add (entry);
|
|
|
|
}
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
2016-02-25 01:55:14 +00:00
|
|
|
|
|
|
|
root.setUserObject (getCatalog ());
|
|
|
|
makeNodeVisible (root.getFirstLeaf ());
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
|
2016-02-25 02:49:12 +00:00
|
|
|
private SectorType getSectorType (String type)
|
|
|
|
{
|
|
|
|
if ("COM".equals (type))
|
|
|
|
return comSector;
|
|
|
|
if ("DOC".equals (type))
|
|
|
|
return docSector;
|
2016-02-25 07:45:24 +00:00
|
|
|
if ("BAS".equals (type))
|
|
|
|
return basSector;
|
|
|
|
if ("PRN".equals (type))
|
|
|
|
return prnSector;
|
2016-02-25 02:49:12 +00:00
|
|
|
|
|
|
|
return dataSector;
|
|
|
|
}
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
@Override
|
|
|
|
public List<DiskAddress> getFileSectors (int fileNo)
|
|
|
|
{
|
2016-02-25 07:45:24 +00:00
|
|
|
if (fileEntries.size () > 0 && fileEntries.size () > fileNo)
|
|
|
|
return fileEntries.get (fileNo).getSectors ();
|
2015-06-01 09:35:51 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-02-24 21:27:03 +00:00
|
|
|
private DirectoryEntry findParent (DirectoryEntry child)
|
|
|
|
{
|
2016-02-25 01:55:14 +00:00
|
|
|
for (AppleFileSource entry : fileEntries)
|
|
|
|
if (((DirectoryEntry) entry).matches (child))
|
|
|
|
return (DirectoryEntry) entry;
|
|
|
|
|
2016-02-24 21:27:03 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-02-25 01:27:22 +00:00
|
|
|
@Override
|
|
|
|
public AppleFileSource getCatalog ()
|
|
|
|
{
|
|
|
|
String newLine = String.format ("%n");
|
2016-02-25 02:49:12 +00:00
|
|
|
String line = "---- --------- ---- ---- ---- ----------------------------"
|
|
|
|
+ "-------------------" + newLine;
|
2016-02-25 01:27:22 +00:00
|
|
|
StringBuilder text = new StringBuilder ();
|
|
|
|
text.append (String.format ("Disk : %s%n%n", getAbsolutePath ()));
|
2016-02-25 02:49:12 +00:00
|
|
|
text.append ("User Name Type Exts Size Blocks" + newLine);
|
2016-02-25 01:27:22 +00:00
|
|
|
text.append (line);
|
|
|
|
|
2016-02-25 01:55:14 +00:00
|
|
|
for (AppleFileSource entry : fileEntries)
|
2016-02-25 01:27:22 +00:00
|
|
|
{
|
2016-02-25 01:55:14 +00:00
|
|
|
text.append (((DirectoryEntry) entry).line ());
|
2016-02-25 01:27:22 +00:00
|
|
|
text.append (newLine);
|
|
|
|
}
|
2016-02-25 02:49:12 +00:00
|
|
|
text.append (line);
|
2016-02-25 01:27:22 +00:00
|
|
|
|
|
|
|
return new DefaultAppleFileSource ("CPM Disk ", text.toString (), this);
|
|
|
|
}
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
public static boolean isCorrectFormat (AppleDisk disk)
|
|
|
|
{
|
|
|
|
disk.setInterleave (3);
|
|
|
|
|
2016-02-24 12:32:36 +00:00
|
|
|
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;
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
for (int sector = 0; sector < 8; sector++)
|
|
|
|
{
|
2016-02-24 12:32:36 +00:00
|
|
|
buffer = disk.readSector (3, sector);
|
2015-06-01 09:35:51 +00:00
|
|
|
for (int i = 0; i < buffer.length; i += 32)
|
|
|
|
{
|
2016-02-24 21:27:03 +00:00
|
|
|
int val = buffer[i] & 0xFF;
|
|
|
|
if (val > 31 && val != 0xE5)
|
2015-06-01 09:35:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|