dmolony-DiskBrowser/src/com/bytezone/diskbrowser/cpm/CPMDisk.java

189 lines
5.4 KiB
Java
Raw Normal View History

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.*;
2016-02-26 03:09:14 +00:00
import com.bytezone.diskbrowser.gui.DataSource;
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);
2016-02-26 11:03:29 +00:00
public final SectorType asmSector = new SectorType ("ASM", Color.orange);
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);
2016-02-26 11:03:29 +00:00
sectorTypesList.add (asmSector);
2015-06-01 09:35:51 +00:00
2016-02-25 07:45:24 +00:00
getDisk ().setEmptyByte ((byte) 0xE5);
setSectorTypes ();
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);
2016-02-25 23:43:44 +00:00
if (disk.isSectorEmpty (da))
break;
2016-02-24 21:27:03 +00:00
2016-02-25 23:43:44 +00:00
sectorTypes[da.getBlock ()] = catalogSector;
2016-02-24 21:27:03 +00:00
buffer = disk.readSector (da);
2016-02-25 23:43:44 +00:00
2016-02-24 21:27:03 +00:00
for (int i = 0; i < buffer.length; i += 32)
{
2016-02-27 23:17:34 +00:00
int val = buffer[i] & 0xFF;
if (val == 0xE5)
2016-02-24 21:27:03 +00:00
break;
2016-02-27 23:17:34 +00:00
DirectoryEntry entry = new DirectoryEntry (this, buffer, i);
SectorType sectorType = getSectorType (entry.getType ());
for (DiskAddress block : entry.getSectors ())
if (!disk.isSectorEmpty (block))
sectorTypes[block.getBlock ()] = sectorType;
DirectoryEntry parent = findParent (entry);
if (parent == null)
2016-02-24 21:27:03 +00:00
{
2016-02-27 23:17:34 +00:00
fileEntries.add (entry);
DefaultMutableTreeNode node = new DefaultMutableTreeNode (entry);
root.add (node);
node.setAllowsChildren (false);
2016-02-24 21:27:03 +00:00
}
2016-02-27 23:17:34 +00:00
else
parent.add (entry);
2016-02-24 21:27:03 +00:00
}
2015-06-01 09:35:51 +00:00
}
2016-02-25 01:55:14 +00:00
2016-02-25 23:43:44 +00:00
root.setUserObject (getCatalog ()); // override the disk's default display
2016-02-25 01:55:14 +00:00
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-26 11:03:29 +00:00
if ("ASM".equals (type))
return asmSector;
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-26 03:09:14 +00:00
@Override
public DataSource getFormattedSector (DiskAddress da)
{
SectorType type = sectorTypes[da.getBlock ()];
byte[] buffer = disk.readSector (da);
if (type == catalogSector)
return new CPMCatalogSector (disk, buffer);
return super.getFormattedSector (da);
}
2016-02-25 01:27:22 +00:00
@Override
public AppleFileSource getCatalog ()
{
String newLine = String.format ("%n");
2016-02-26 03:09:14 +00:00
String line =
2016-02-26 23:10:00 +00:00
"---- --------- --- - - -- -- -- -- ----------------------------"
2016-02-26 03:09:14 +00:00
+ "-------------------" + newLine;
2016-02-25 01:27:22 +00:00
StringBuilder text = new StringBuilder ();
text.append (String.format ("Disk : %s%n%n", getAbsolutePath ()));
2016-02-26 23:10:00 +00:00
text.append ("User Name Typ R S Ex S2 S1 RC 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;
2016-02-27 22:16:36 +00:00
if (val == 0xE5)
return true;
if (val > 31)
2015-06-01 09:35:51 +00:00
return false;
2016-02-27 23:17:34 +00:00
for (int j = 1; j <= 8; j++)
{
val = buffer[i + j] & 0xFF;
// System.out.printf ("%3d %s%n", val, (char) val);
if (val < 32 || val > 126)
return false;
}
2015-06-01 09:35:51 +00:00
}
}
return true;
}
}