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,8 +91,9 @@ public class DirectoryEntry implements AppleFileSource
for (DirectoryEntry entry : entries)
{
bytes = HexFormatter.getHexString (entry.blockList, 0, 16);
bytes = bytes.replaceAll ("00", " ");
text = text + String.format ("%n%-36.36s%s", "", bytes);
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

@ -76,7 +76,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
* have to append their catalog entries to this node.
*/
DefaultAppleFileSource afs =
new DefaultAppleFileSource (getName (), disk.toString (), this);
new DefaultAppleFileSource (getName (), disk.toString (), this);
DefaultMutableTreeNode root = new DefaultMutableTreeNode (afs);
DefaultTreeModel treeModel = new DefaultTreeModel (root);
catalogTree = new JTree (treeModel);
@ -95,7 +95,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
});
}
private void setSectorTypes ()
protected void setSectorTypes ()
{
sectorTypes = new SectorType[disk.getTotalBlocks ()];
@ -156,9 +156,10 @@ 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);
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)
@ -344,7 +345,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
public boolean stillAvailable (DiskAddress da)
{
return sectorTypes[da.getBlock ()] == usedSector
|| sectorTypes[da.getBlock ()] == emptySector;
|| sectorTypes[da.getBlock ()] == emptySector;
}
@Override
@ -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;
@ -293,7 +295,7 @@ public class AppleDisk implements Disk
int bufferOffset = 0;
for (DiskAddress da : daList)
{
if (da != null) // text files may have gaps
if (da != null) // text files may have gaps
readBuffer (da, buffer, bufferOffset);
bufferOffset += sectorSize;
}
@ -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,17 +8,19 @@ public interface Disk extends Iterable<DiskAddress>
{
public long getBootChecksum ();
public int getTotalBlocks (); // blocks per disk - usually 560 or 280
public void setEmptyByte (byte value);
public int getTotalTracks (); // usually 35
public int getTotalBlocks (); // blocks per disk - usually 560 or 280
public int getBlockSize (); // bytes per block - 256 or 512
public int getTotalTracks (); // usually 35
public int getBlockSize (); // bytes per block - 256 or 512
public void setBlockSize (int blockSize);
public int getTrackSize (); // bytes per track - 4096
public int getTrackSize (); // bytes per track - 4096
public int getSectorsPerTrack (); // 8 or 16
public int getSectorsPerTrack (); // 8 or 16
public void setInterleave (int interleave);

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
@ -248,12 +243,10 @@ public class DosDisk extends AbstractFormattedDisk
// if (buffer[1] != 0x11) // first catalog track
// return 0;
if (buffer[53] != 16 && buffer[53] != 13) // tracks per sector
{
// System.out.println ("VTOC tracks per sector : " + (buffer[53 & 0xFF]));
if (buffer[53] != 16 && buffer[53] != 13) // tracks per sector
return 0;
}
if (buffer[49] < -1 || buffer[49] > 1) // direction of next file save
if (buffer[49] < -1 || buffer[49] > 1) // direction of next file save
{
System.out.println ("Bad direction : " + buffer[49]);
// Visicalc data disk had 0xF8
@ -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

@ -18,243 +18,246 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
public class InfocomDisk extends AbstractFormattedDisk
{
private static final int BLOCK_SIZE = 256;
private static final boolean TYPE_NODE = true;
private static final boolean TYPE_LEAF = false;
private byte[] data;
int version;
Header header;
private static final int BLOCK_SIZE = 256;
private static final boolean TYPE_NODE = true;
private static final boolean TYPE_LEAF = false;
private byte[] data;
int version;
Header header;
Color green = new Color (0, 200, 0);
Color green = new Color (0, 200, 0);
SectorType bootSector = new SectorType ("Boot code", Color.lightGray);
SectorType stringsSector = new SectorType ("Strings", Color.magenta);
SectorType objectsSector = new SectorType ("Objects", green);
SectorType dictionarySector = new SectorType ("Dictionary", Color.blue);
SectorType abbreviationsSector = new SectorType ("Abbreviations", Color.red);
SectorType codeSector = new SectorType ("Code", Color.orange);
SectorType headerSector = new SectorType ("Header", Color.cyan);
SectorType globalsSector = new SectorType ("Globals", Color.darkGray);
SectorType grammarSector = new SectorType ("Grammar", Color.gray);
SectorType bootSector = new SectorType ("Boot code", Color.lightGray);
SectorType stringsSector = new SectorType ("Strings", Color.magenta);
SectorType objectsSector = new SectorType ("Objects", green);
SectorType dictionarySector = new SectorType ("Dictionary", Color.blue);
SectorType abbreviationsSector = new SectorType ("Abbreviations", Color.red);
SectorType codeSector = new SectorType ("Code", Color.orange);
SectorType headerSector = new SectorType ("Header", Color.cyan);
SectorType globalsSector = new SectorType ("Globals", Color.darkGray);
SectorType grammarSector = new SectorType ("Grammar", Color.gray);
public InfocomDisk (Disk disk)
{
super (disk);
public InfocomDisk (Disk disk)
{
super (disk);
setSectorTypes ();
setSectorTypes ();
data = disk.readSector (3, 0); // read first sector to get file size
data = getBuffer (getWord (26) * 2); // read entire file into data buffer
data = disk.readSector (3, 0); // read first sector to get file size
data = getBuffer (getWord (26) * 2); // read entire file into data buffer
if (false)
createStoryFile ("Zork1.sf");
if (false)
createStoryFile ("Zork1.sf");
DefaultMutableTreeNode root = getCatalogTreeRoot ();
DefaultMutableTreeNode codeNode = null;
DefaultMutableTreeNode objectNode = null;
DefaultMutableTreeNode root = getCatalogTreeRoot ();
DefaultMutableTreeNode codeNode = null;
DefaultMutableTreeNode objectNode = null;
header = new Header ("Header", data, disk.getFile ());
header = new Header ("Header", data, disk.getFile ());
addToTree (root, "Header", header, TYPE_LEAF);
addToTree (root, "Abbreviations", header.abbreviations, TYPE_LEAF);
addToTree (root, "Header", header, TYPE_LEAF);
addToTree (root, "Abbreviations", header.abbreviations, TYPE_LEAF);
objectNode = addToTree (root, "Objects", header.objectManager, TYPE_NODE);
header.objectManager.addNodes (objectNode, this);
addToTree (root, "Globals", header.globals, TYPE_LEAF);
addToTree (root, "Grammar", header.grammar, TYPE_LEAF);
addToTree (root, "Dictionary", header.dictionary, TYPE_LEAF);
codeNode = addToTree (root, "Code", header.codeManager, TYPE_NODE);
header.codeManager.addNodes (codeNode, this);
objectNode = addToTree (root, "Objects", header.objectManager, TYPE_NODE);
header.objectManager.addNodes (objectNode, this);
addToTree (root, "Globals", header.globals, TYPE_LEAF);
addToTree (root, "Grammar", header.grammar, TYPE_LEAF);
addToTree (root, "Dictionary", header.dictionary, TYPE_LEAF);
codeNode = addToTree (root, "Code", header.codeManager, TYPE_NODE);
header.codeManager.addNodes (codeNode, this);
addToTree (root, "Strings", header.stringManager, TYPE_LEAF);
addToTree (root, "Strings", header.stringManager, TYPE_LEAF);
PropertyManager pm = new PropertyManager ("Properties", data, header);
pm.addNodes (addToTree (objectNode, "Properties", pm, TYPE_NODE), this);
PropertyManager pm = new PropertyManager ("Properties", data, header);
pm.addNodes (addToTree (objectNode, "Properties", pm, TYPE_NODE), this);
AttributeManager am = new AttributeManager ("Attributes", data, header);
am.addNodes (addToTree (objectNode, "Attributes", am, TYPE_NODE), this);
AttributeManager am = new AttributeManager ("Attributes", data, header);
am.addNodes (addToTree (objectNode, "Attributes", am, TYPE_NODE), this);
sectorTypes[48] = headerSector;
sectorTypes[48] = headerSector;
setSectors (header.abbreviationsTable, header.objectTable, abbreviationsSector);
setSectors (header.objectTable, header.globalsOffset, objectsSector);
setSectors (header.globalsOffset, header.staticMemory, globalsSector);
setSectors (header.staticMemory, header.dictionaryOffset, grammarSector);
setSectors (header.dictionaryOffset, header.highMemory, dictionarySector);
setSectors (header.highMemory, header.stringPointer, codeSector);
setSectors (header.stringPointer, header.fileLength, stringsSector);
}
setSectors (header.abbreviationsTable, header.objectTable, abbreviationsSector);
setSectors (header.objectTable, header.globalsOffset, objectsSector);
setSectors (header.globalsOffset, header.staticMemory, globalsSector);
setSectors (header.staticMemory, header.dictionaryOffset, grammarSector);
setSectors (header.dictionaryOffset, header.highMemory, dictionarySector);
setSectors (header.highMemory, header.stringPointer, codeSector);
setSectors (header.stringPointer, header.fileLength, stringsSector);
}
private void setSectorTypes ()
{
sectorTypesList.add (bootSector);
sectorTypesList.add (headerSector);
sectorTypesList.add (abbreviationsSector);
sectorTypesList.add (objectsSector);
sectorTypesList.add (globalsSector);
sectorTypesList.add (grammarSector);
sectorTypesList.add (dictionarySector);
sectorTypesList.add (codeSector);
sectorTypesList.add (stringsSector);
@Override
protected void setSectorTypes ()
{
sectorTypesList.add (bootSector);
sectorTypesList.add (headerSector);
sectorTypesList.add (abbreviationsSector);
sectorTypesList.add (objectsSector);
sectorTypesList.add (globalsSector);
sectorTypesList.add (grammarSector);
sectorTypesList.add (dictionarySector);
sectorTypesList.add (codeSector);
sectorTypesList.add (stringsSector);
for (int track = 0; track < 3; track++)
for (int sector = 0; sector < 16; sector++)
if (!disk.isSectorEmpty (track, sector))
sectorTypes[track * 16 + sector] = bootSector;
}
for (int track = 0; track < 3; track++)
for (int sector = 0; sector < 16; sector++)
if (!disk.isSectorEmpty (track, sector))
sectorTypes[track * 16 + sector] = bootSector;
}
private void setSectors (int sectorFrom, int sectorTo, SectorType type)
{
int blockNo = sectorFrom / disk.getBlockSize () + 48;
int blockTo = sectorTo / disk.getBlockSize () + 48;
while (blockNo <= blockTo)
{
if (!disk.isSectorEmpty (blockNo))
sectorTypes[blockNo] = type;
blockNo++;
}
}
private void setSectors (int sectorFrom, int sectorTo, SectorType type)
{
int blockNo = sectorFrom / disk.getBlockSize () + 48;
int blockTo = sectorTo / disk.getBlockSize () + 48;
while (blockNo <= blockTo)
{
if (!disk.isSectorEmpty (blockNo))
sectorTypes[blockNo] = type;
blockNo++;
}
}
private int getFileSize ()
{
byte[] buffer = null;
int startBlock = getWord (4) / 256 + 48;
int fileSize = 0;
for (DiskAddress da : disk)
{
if (da.getBlock () > startBlock && disk.isSectorEmpty (da))
{
out.println ("Empty : " + da);
buffer = disk.readSector (da.getBlock () - 1);
fileSize = (da.getBlock () - 48) * disk.getBlockSize ();
break;
}
}
int ptr = 255;
while (buffer[ptr--] == 0)
fileSize--;
return fileSize;
}
private int getFileSize ()
{
byte[] buffer = null;
int startBlock = getWord (4) / 256 + 48;
int fileSize = 0;
for (DiskAddress da : disk)
{
if (da.getBlock () > startBlock && disk.isSectorEmpty (da))
{
out.println ("Empty : " + da);
buffer = disk.readSector (da.getBlock () - 1);
fileSize = (da.getBlock () - 48) * disk.getBlockSize ();
break;
}
}
int ptr = 255;
while (buffer[ptr--] == 0)
fileSize--;
return fileSize;
}
private byte[] getBuffer (int fileSize)
{
if (fileSize == 0)
fileSize = getFileSize ();
System.out.println ("File size : " + fileSize);
data = new byte[fileSize];
private byte[] getBuffer (int fileSize)
{
if (fileSize == 0)
fileSize = getFileSize ();
System.out.println ("File size : " + fileSize);
data = new byte[fileSize];
for (int track = 3, ptr = 0; track < 35; track++)
for (int sector = 0; sector < 16; sector++, ptr += BLOCK_SIZE)
{
byte[] temp = disk.readSector (track, sector);
int spaceLeft = fileSize - ptr;
if (spaceLeft <= BLOCK_SIZE)
{
System.arraycopy (temp, 0, data, ptr, spaceLeft);
return data;
}
System.arraycopy (temp, 0, data, ptr, BLOCK_SIZE);
}
return data;
}
for (int track = 3, ptr = 0; track < 35; track++)
for (int sector = 0; sector < 16; sector++, ptr += BLOCK_SIZE)
{
byte[] temp = disk.readSector (track, sector);
int spaceLeft = fileSize - ptr;
if (spaceLeft <= BLOCK_SIZE)
{
System.arraycopy (temp, 0, data, ptr, spaceLeft);
return data;
}
System.arraycopy (temp, 0, data, ptr, BLOCK_SIZE);
}
return data;
}
private DefaultMutableTreeNode addToTree (DefaultMutableTreeNode root, String title,
DataSource af, boolean allowsChildren)
{
DefaultMutableTreeNode node =
new DefaultMutableTreeNode (new DefaultAppleFileSource (title, af, this));
node.setAllowsChildren (allowsChildren);
root.add (node);
return node;
}
private DefaultMutableTreeNode addToTree (DefaultMutableTreeNode root, String title,
DataSource af, boolean allowsChildren)
{
DefaultMutableTreeNode node =
new DefaultMutableTreeNode (new DefaultAppleFileSource (title, af, this));
node.setAllowsChildren (allowsChildren);
root.add (node);
return node;
}
public List<DiskAddress> getFileSectors (int fileNo)
{
return null;
}
@Override
public List<DiskAddress> getFileSectors (int fileNo)
{
return null;
}
@Override
public AppleFileSource getCatalog ()
{
return new DefaultAppleFileSource (header.getText (), this);
}
@Override
public AppleFileSource getCatalog ()
{
return new DefaultAppleFileSource (header.getText (), this);
}
public static boolean isCorrectFormat (AppleDisk disk)
{
disk.setInterleave (2);
return checkFormat (disk);
}
public static boolean isCorrectFormat (AppleDisk disk)
{
disk.setInterleave (2);
return checkFormat (disk);
}
public static boolean checkFormat (AppleDisk disk)
{
byte[] buffer = disk.readSector (3, 0);
public static boolean checkFormat (AppleDisk disk)
{
byte[] buffer = disk.readSector (3, 0);
int version = buffer[0] & 0xFF;
int highMemory = HexFormatter.intValue (buffer[5], buffer[4]);
int programCounter = HexFormatter.intValue (buffer[7], buffer[6]);
int dictionary = HexFormatter.intValue (buffer[9], buffer[8]);
int objectTable = HexFormatter.intValue (buffer[11], buffer[10]);
int globals = HexFormatter.intValue (buffer[13], buffer[12]);
int staticMemory = HexFormatter.intValue (buffer[15], buffer[14]);
int abbreviationsTable = HexFormatter.intValue (buffer[25], buffer[24]);
int fileLength = HexFormatter.intValue (buffer[27], buffer[26]);
int version = buffer[0] & 0xFF;
int highMemory = HexFormatter.intValue (buffer[5], buffer[4]);
int programCounter = HexFormatter.intValue (buffer[7], buffer[6]);
int dictionary = HexFormatter.intValue (buffer[9], buffer[8]);
int objectTable = HexFormatter.intValue (buffer[11], buffer[10]);
int globals = HexFormatter.intValue (buffer[13], buffer[12]);
int staticMemory = HexFormatter.intValue (buffer[15], buffer[14]);
int abbreviationsTable = HexFormatter.intValue (buffer[25], buffer[24]);
int fileLength = HexFormatter.intValue (buffer[27], buffer[26]);
if (false)
{
System.out.printf ("Version %,6d%n", version);
System.out.printf ("Abbreviations %,6d%n", abbreviationsTable);
System.out.printf ("Objects %,6d%n", objectTable);
System.out.printf ("Globals %,6d%n", globals);
System.out.printf ("Static memory %,6d%n", staticMemory);
System.out.printf ("Dictionary %,6d%n", dictionary);
System.out.printf ("High memory %,6d%n", highMemory);
System.out.printf ("Program counter %,6d%n", programCounter);
System.out.printf ("File length %,6d%n", fileLength);
}
if (false)
{
System.out.printf ("Version %,6d%n", version);
System.out.printf ("Abbreviations %,6d%n", abbreviationsTable);
System.out.printf ("Objects %,6d%n", objectTable);
System.out.printf ("Globals %,6d%n", globals);
System.out.printf ("Static memory %,6d%n", staticMemory);
System.out.printf ("Dictionary %,6d%n", dictionary);
System.out.printf ("High memory %,6d%n", highMemory);
System.out.printf ("Program counter %,6d%n", programCounter);
System.out.printf ("File length %,6d%n", fileLength);
}
if (abbreviationsTable >= objectTable)
return false;
if (objectTable >= globals)
return false;
if (globals >= staticMemory)
return false;
if (staticMemory >= dictionary)
return false;
if (dictionary >= highMemory)
return false;
// if (highMemory > programCounter)
// return false;
if (abbreviationsTable >= objectTable)
return false;
if (objectTable >= globals)
return false;
if (globals >= staticMemory)
return false;
if (staticMemory >= dictionary)
return false;
if (dictionary >= highMemory)
return false;
// if (highMemory > programCounter)
// return false;
if (version < 2 || version > 3)
{
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);
return false;
}
if (version < 2 || version > 3)
{
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);
return false;
}
return true;
}
return true;
}
private int getWord (int offset)
{
return (((data[offset] << 8) & 0xFF00) | ((data[offset + 1]) & 0xFF));
}
private int getWord (int offset)
{
return (((data[offset] << 8) & 0xFF00) | ((data[offset + 1]) & 0xFF));
}
private void createStoryFile (String fileName)
{
File f = new File (fileName);
try
{
FileOutputStream fos = new FileOutputStream (f);
fos.write (data);
fos.close ();
}
catch (IOException e)
{
e.printStackTrace ();
}
}
private void createStoryFile (String fileName)
{
File f = new File (fileName);
try
{
FileOutputStream fos = new FileOutputStream (f);
fos.write (data);
fos.close ();
}
catch (IOException e)
{
e.printStackTrace ();
}
}
}