CPM support

This commit is contained in:
Denis Molony 2016-02-25 18:45:24 +11:00
parent 37b0f587e7
commit d535da2116
9 changed files with 283 additions and 257 deletions

View File

@ -6,18 +6,18 @@ 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 prnSector = new SectorType ("PRN", 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);
public final SectorType basSector = new SectorType ("BAS", Color.gray);
private int version; // http://www.seasip.info/Cpm/format22.html
@ -26,15 +26,17 @@ public class CPMDisk extends AbstractFormattedDisk
super (disk);
sectorTypesList.add (catalogSector);
sectorTypesList.add (cpmSector);
sectorTypesList.add (prnSector);
sectorTypesList.add (comSector);
sectorTypesList.add (dataSector);
sectorTypesList.add (xxxSector);
sectorTypesList.add (basSector);
sectorTypesList.add (docSector);
byte[] sectorBuffer = disk.readSector (0, 0); // Boot sector
bootSector = new BootSector (disk, sectorBuffer, "CPM");
sectorTypes[0] = cpmSector;
getDisk ().setEmptyByte ((byte) 0xE5);
setSectorTypes ();
// byte[] sectorBuffer = disk.readSector (0, 0); // Boot sector
// bootSector = new BootSector (disk, sectorBuffer, "CPM");
byte[] buffer = disk.readSector (0, 8);
String text = new String (buffer, 16, 24);
@ -84,6 +86,10 @@ public class CPMDisk extends AbstractFormattedDisk
return comSector;
if ("DOC".equals (type))
return docSector;
if ("BAS".equals (type))
return basSector;
if ("PRN".equals (type))
return prnSector;
return dataSector;
}
@ -91,6 +97,8 @@ public class CPMDisk extends AbstractFormattedDisk
@Override
public List<DiskAddress> getFileSectors (int fileNo)
{
if (fileEntries.size () > 0 && fileEntries.size () > fileNo)
return fileEntries.get (fileNo).getSectors ();
return null;
}

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.applefile.AppleFileSource;
import com.bytezone.diskbrowser.applefile.DefaultAppleFile;
import com.bytezone.diskbrowser.disk.AppleDiskAddress;
import com.bytezone.diskbrowser.disk.Disk;
import com.bytezone.diskbrowser.disk.DiskAddress;
@ -13,6 +14,7 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
public class DirectoryEntry implements AppleFileSource
{
private final Disk disk;
private final CPMDisk parent;
private final int userNumber;
private final String name;
@ -24,10 +26,13 @@ public class DirectoryEntry implements AppleFileSource
private final byte[] blockList = new byte[16];
private final List<DirectoryEntry> entries = new ArrayList<DirectoryEntry> ();
private final List<DiskAddress> blocks = new ArrayList<DiskAddress> ();
private DataSource appleFile;
public DirectoryEntry (CPMDisk parent, byte[] buffer, int offset)
{
this.parent = parent;
disk = parent.getDisk ();
userNumber = buffer[offset] & 0xFF;
name = new String (buffer, offset + 1, 8).trim ();
type = new String (buffer, offset + 9, 3).trim ();
@ -86,7 +91,8 @@ public class DirectoryEntry implements AppleFileSource
for (DirectoryEntry entry : entries)
{
bytes = HexFormatter.getHexString (entry.blockList, 0, 16);
bytes = bytes.replaceAll ("00", " ");
bytes = bytes.replaceAll ("00", " ").trim ();
if (!bytes.isEmpty ())
text = text + String.format ("%n%-36.36s%s", "", bytes);
}
return text;
@ -126,7 +132,17 @@ public class DirectoryEntry implements AppleFileSource
@Override
public DataSource getDataSource ()
{
return null;
if (appleFile != null)
return appleFile;
byte[] buffer = disk.readSectors (blocks);
if (buffer.length == 0)
{
appleFile = new DefaultAppleFile (name, buffer);
return appleFile;
}
appleFile = new DefaultAppleFile (name, buffer);
return appleFile;
}
@Override

View File

@ -95,7 +95,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
});
}
private void setSectorTypes ()
protected void setSectorTypes ()
{
sectorTypes = new SectorType[disk.getTotalBlocks ()];
@ -156,7 +156,8 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
{
this.originalPath = path;
DefaultMutableTreeNode root = (DefaultMutableTreeNode) catalogTree.getModel ().getRoot ();
DefaultMutableTreeNode root =
(DefaultMutableTreeNode) catalogTree.getModel ().getRoot ();
DefaultAppleFileSource afs =
new DefaultAppleFileSource (getName (), disk.toString (), this);
root.setUserObject (afs);
@ -215,8 +216,8 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
public void makeNodeVisible (DefaultMutableTreeNode node)
{
catalogTree.makeVisible (new TreePath (((DefaultTreeModel) catalogTree.getModel ())
.getPathToRoot (node)));
catalogTree.makeVisible (new TreePath (
((DefaultTreeModel) catalogTree.getModel ()).getPathToRoot (node)));
}
protected DefaultMutableTreeNode findNode (DefaultMutableTreeNode node, String name)
@ -405,7 +406,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
public void notifyListeners (String text)
{
if (actionListenerList != null)
actionListenerList.actionPerformed (new ActionEvent (this, ActionEvent.ACTION_PERFORMED,
text));
actionListenerList
.actionPerformed (new ActionEvent (this, ActionEvent.ACTION_PERFORMED, text));
}
}

View File

@ -46,6 +46,8 @@ public class AppleDisk implements Disk
// Position: 0 7 E 6 D 5 C 4 B 3 A 2 9 1 8 F - Dos (.DO disks)
private boolean[] hasData;
private byte emptyByte = 0;
private ActionListener actionListenerList;
private List<DiskAddress> blockList;
@ -212,7 +214,7 @@ public class AppleDisk implements Disk
byte[] buffer = readSector (da);
hasData[da.getBlock ()] = false;
for (int i = 0; i < sectorSize; i++)
if (buffer[i] != 0)
if (buffer[i] != emptyByte)
{
hasData[da.getBlock ()] = true;
break;
@ -504,4 +506,11 @@ public class AppleDisk implements Disk
checksum.update (buffer, 0, buffer.length);
return checksum.getValue ();
}
@Override
public void setEmptyByte (byte value)
{
emptyByte = value;
checkSectorsForData ();
}
}

View File

@ -8,6 +8,8 @@ public interface Disk extends Iterable<DiskAddress>
{
public long getBootChecksum ();
public void setEmptyByte (byte value);
public int getTotalBlocks (); // blocks per disk - usually 560 or 280
public int getTotalTracks (); // usually 35

View File

@ -20,7 +20,7 @@ import com.bytezone.diskbrowser.wizardry.WizardryScenarioDisk;
public class DiskFactory
{
private static boolean debug = true;
private static boolean debug = false;
private DiskFactory ()
{

View File

@ -13,14 +13,14 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
abstract class AbstractCatalogEntry implements AppleFileSource
{
Disk disk;
DosDisk dosDisk;
String name;
String catalogName;
protected Disk disk;
protected DosDisk dosDisk;
protected String name;
protected String catalogName;
FileType fileType;
int reportedSize;
boolean locked;
protected FileType fileType;
protected int reportedSize;
protected boolean locked;
protected DataSource appleFile;
protected DiskAddress catalogSectorDA;

View File

@ -17,8 +17,6 @@ public class DosDisk extends AbstractFormattedDisk
private static final int ENTRY_SIZE = 35;
private static final int CATALOG_TRACK = 17;
// private static final boolean CHECK_SELF_POINTER = true;
private final DosVTOCSector dosVTOCSector;
private final Color green = new Color (0, 200, 0);
private final DefaultMutableTreeNode volumeNode;
@ -158,9 +156,6 @@ public class DosDisk extends AbstractFormattedDisk
// int thisBlock = da.getBlock ();
da = disk.getDiskAddress (sectorBuffer[1], sectorBuffer[2]);
// if (CHECK_SELF_POINTER && da.getBlock () == thisBlock)
// break;
} while (da.getBlock () != 0);
// add up all the free and used sectors, and label DOS sectors while we're here
@ -249,10 +244,8 @@ public class DosDisk extends AbstractFormattedDisk
// return 0;
if (buffer[53] != 16 && buffer[53] != 13) // tracks per sector
{
// System.out.println ("VTOC tracks per sector : " + (buffer[53 & 0xFF]));
return 0;
}
if (buffer[49] < -1 || buffer[49] > 1) // direction of next file save
{
System.out.println ("Bad direction : " + buffer[49]);
@ -279,7 +272,6 @@ public class DosDisk extends AbstractFormattedDisk
do
{
// System.out.printf ("%5d %s%n", catalogBlocks, da);
if (!disk.isValidAddress (da))
break;
@ -293,8 +285,6 @@ public class DosDisk extends AbstractFormattedDisk
if (!disk.isValidAddress (buffer[1], buffer[2]))
{
System.out.printf ("Invalid address : %02X / %02X%n", buffer[1], buffer[2]);
// System.out.println (HexFormatter.format (buffer));
// System.out.println (da);
break;
}
@ -309,9 +299,6 @@ public class DosDisk extends AbstractFormattedDisk
// int thisBlock = da.getBlock ();
da = disk.getDiskAddress (buffer[1], buffer[2]);
// if (CHECK_SELF_POINTER && da.getBlock () == thisBlock)
// break;
} while (da.getBlock () != 0);
// if (catalogBlocks != catalogAddresses.size ())

View File

@ -85,7 +85,8 @@ public class InfocomDisk extends AbstractFormattedDisk
setSectors (header.stringPointer, header.fileLength, stringsSector);
}
private void setSectorTypes ()
@Override
protected void setSectorTypes ()
{
sectorTypesList.add (bootSector);
sectorTypesList.add (headerSector);
@ -168,6 +169,7 @@ public class InfocomDisk extends AbstractFormattedDisk
return node;
}
@Override
public List<DiskAddress> getFileSectors (int fileNo)
{
return null;
@ -229,9 +231,10 @@ public class InfocomDisk extends AbstractFormattedDisk
{
System.out.println ("Incorrect format : " + version);
JOptionPane
.showMessageDialog (null, "This appears to be an Infocom disk," + " but version "
+ version + " is not supported", "Unknown disk format",
JOptionPane.INFORMATION_MESSAGE);
.showMessageDialog (null,
"This appears to be an Infocom disk," + " but version "
+ version + " is not supported",
"Unknown disk format", JOptionPane.INFORMATION_MESSAGE);
return false;
}