diff --git a/src/com/bytezone/diskbrowser/applefile/Relocator.java b/src/com/bytezone/diskbrowser/applefile/Relocator.java index 9843592..62bdf0c 100644 --- a/src/com/bytezone/diskbrowser/applefile/Relocator.java +++ b/src/com/bytezone/diskbrowser/applefile/Relocator.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.bytezone.diskbrowser.disk.AppleDisk; import com.bytezone.diskbrowser.utilities.HexFormatter; public class Relocator extends AbstractFile @@ -15,6 +16,12 @@ public class Relocator extends AbstractFile private final List newAddresses = new ArrayList (); private final List oldAddresses = new ArrayList (); + private final List logicalAddresses = + new ArrayList (); + private final byte[] diskBlocks = new byte[0x800]; + private final int[] diskOffsets = new int[0x800]; + private final AppleDisk[] disks = new AppleDisk[5]; + public Relocator (String name, byte[] buffer) { super (name, buffer); @@ -30,11 +37,16 @@ public class Relocator extends AbstractFile ptr += diskRecord.size (); } + logicalAddresses.add (new MultiDiskAddress (0, 0, 0, 0x800)); + for (DiskRecord diskRecord : diskRecords) for (DiskSegment diskSegment : diskRecord.diskSegments) + { addresses .add (new MultiDiskAddress (diskRecord.diskNumber, diskSegment.logicalBlock, diskSegment.physicalBlock, diskSegment.segmentLength)); + addLogicalBlock ((byte) diskRecord.diskNumber, diskSegment); + } getMultiDiskAddress ("BOOT", 0, 2); getMultiDiskAddress ("CATALOG", 2, 4); @@ -48,6 +60,18 @@ public class Relocator extends AbstractFile multiDiskAddress.totalBlocks, multiDiskAddress.name); } + private void addLogicalBlock (byte disk, DiskSegment diskSegment) + { + int lo = diskSegment.logicalBlock; + int hi = diskSegment.logicalBlock + diskSegment.segmentLength; + for (int i = lo; i < hi; i++) + if (diskBlocks[i] == 0) + { + diskBlocks[i] = disk; + diskOffsets[i] = diskSegment.physicalBlock; + } + } + public List getMultiDiskAddress (String name, int blockNumber, int length) { @@ -93,6 +117,22 @@ public class Relocator extends AbstractFile return foundAddresses; } + public void addDisk (AppleDisk disk) + { + byte[] buffer = disk.readSector (1); + int diskNo = buffer[510] & 0xFF; + if (diskNo > 0 && diskNo <= 5) + disks[diskNo - 1] = disk; + } + + public boolean hasData () + { + for (AppleDisk disk : disks) + if (disk == null) + return false; + return true; + } + @Override public String getText () { @@ -115,7 +155,7 @@ public class Relocator extends AbstractFile previousDiskNumber = multiDiskAddress.diskNumber; text.append ("\n"); text.append ("Disk Logical Physical Size Name\n"); - text.append ("---- ------- -------- ---- -----------\n"); + text.append ("---- ------- -------- ---- -------------\n"); } text.append (String.format (" %d %03X %03X %03X %s%n", multiDiskAddress.diskNumber, multiDiskAddress.logicalBlockNumber, @@ -123,6 +163,36 @@ public class Relocator extends AbstractFile multiDiskAddress.name)); } + text.append ("\n\n Logical Size Disk Physical"); + text.append ("\n--------- ---- ---- ---------\n"); + + int first = 0; + int lastDisk = diskBlocks[0]; + int lastOffset = diskOffsets[0]; + for (int i = 0; i < diskBlocks.length; i++) + { + if (diskBlocks[i] != lastDisk || diskOffsets[i] != lastOffset) + { + int size = i - first; + if (lastDisk > 0) + text.append (String.format ("%03X - %03X %03X %d %03X - %03X%n", first, + i - 1, size, lastDisk, lastOffset, lastOffset + size - 1)); + else + text.append (String.format ("%03X - %03X %03X%n", first, i - 1, size)); + first = i; + lastDisk = diskBlocks[i]; + lastOffset = diskOffsets[i]; + } + } + + if (lastDisk > 0) + { + int max = diskBlocks.length; + int size = max - first; + text.append (String.format ("%03X - %03X %03X %d %03X - %03X%n", first, + max - 1, size, lastDisk, lastOffset, lastOffset + size - 1)); + } + return text.toString (); } @@ -157,11 +227,24 @@ public class Relocator extends AbstractFile text.append (String.format ("Disk number.... %04X%n", diskNumber)); text.append (String.format ("Segments....... %04X%n%n", totDiskSegments)); - text.append (String.format ("Segment Logical Physical Length%n")); + text.append (String.format (" Seg Skip Size Logical Physical%n")); + text.append (String.format (" --- ---- ---- ----------- -----------%n")); int count = 1; + int last = 0; + int size = 0; + for (DiskSegment segment : diskSegments) - text.append (String.format (" %02X %s %n", count++, segment.toString ())); + { + if (segment.logicalBlock > last) + { + int end = segment.logicalBlock - 1; + size = end - last + 1; + } + last = segment.logicalBlock + segment.segmentLength; + text.append ( + String.format (" %02X %04X %s %n", count++, size, segment.toString ())); + } return text.toString (); } @@ -183,20 +266,21 @@ public class Relocator extends AbstractFile @Override public String toString () { - return String.format (" %04X %04X %04X", logicalBlock, physicalBlock, - segmentLength); + return String.format (" %04X %04X - %04X %04X - %04X", segmentLength, + logicalBlock, (logicalBlock + segmentLength - 1), physicalBlock, + (physicalBlock + segmentLength - 1)); } - public String toString (int offset) - { - int logical = logicalBlock - offset; - int physical = physicalBlock - offset; - if (physical >= 0) - return String.format (" %04X %04X %04X %04X %04X", - logicalBlock, physicalBlock, segmentLength, logical, physical); - return String.format (" %04X %04X %04X", logicalBlock, physicalBlock, - segmentLength); - } + // public String toString (int offset) + // { + // int logical = logicalBlock - offset; + // int physical = physicalBlock - offset; + // if (physical >= 0) + // return String.format (" %04X %04X %04X %04X %04X", + // logicalBlock, physicalBlock, segmentLength, logical, physical); + // return String.format (" %04X %04X %04X", logicalBlock, physicalBlock, + // segmentLength); + // } } class MultiDiskAddress implements Comparable diff --git a/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java b/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java index ebea23b..65e60c2 100755 --- a/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java +++ b/src/com/bytezone/diskbrowser/disk/AbstractFormattedDisk.java @@ -95,7 +95,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk protected void setEmptyByte (byte value) { - getDisk ().setEmptyByte ((byte) 0xE5); + getDisk ().setEmptyByte (value); setSectorTypes (); } @@ -130,6 +130,10 @@ public abstract class AbstractFormattedDisk implements FormattedDisk gridLayout = new Dimension (16, 100); break; + case 2048: + gridLayout = new Dimension (8, 256); + break; + default: int[] sizes = { 32, 20, 16, 8 }; for (int size : sizes) @@ -237,8 +241,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) diff --git a/src/com/bytezone/diskbrowser/disk/AppleDisk.java b/src/com/bytezone/diskbrowser/disk/AppleDisk.java index 056233b..c112b11 100755 --- a/src/com/bytezone/diskbrowser/disk/AppleDisk.java +++ b/src/com/bytezone/diskbrowser/disk/AppleDisk.java @@ -20,8 +20,10 @@ import com.bytezone.diskbrowser.utilities.HexFormatter; public class AppleDisk implements Disk { - static final String newLine = String.format ("%n"); - static final int MAX_INTERLEAVE = 3; + private static final String newLine = String.format ("%n"); + private static final int MAX_INTERLEAVE = 3; + private static final int SECTOR_SIZE = 256; + private static final int BLOCK_SIZE = 512; public final File path; private final byte[] diskBuffer; // contains the disk contents in memory @@ -89,13 +91,13 @@ public class AppleDisk implements Disk String name = path.getName (); int pos = name.lastIndexOf ('.'); + String suffix = pos > 0 ? name.substring (pos + 1) : ""; + byte[] buffer = getPrefix (path); // HDV could be a 2mg String prefix = new String (buffer, 0, 4); int skip = 0; - if ((pos > 0 && name.substring (pos + 1).equalsIgnoreCase ("2mg")) - || "2IMG".equals (prefix)) - // if ("2IMG".equals (prefix)) + if (suffix.equalsIgnoreCase ("2mg") || "2IMG".equals (prefix)) { if (debug) System.out.println (Utility.toHex (buffer)); @@ -125,11 +127,11 @@ public class AppleDisk implements Disk // int format = buffer[12] & 0xFF; // if (blocks == 0 && format == 1) - { - this.blocks = diskData / 4096 * 8; // reduces blocks to a legal multiple - if (debug) - System.out.printf ("Blocks : %,d%n", blocks); - } + // { + this.blocks = diskData / 4096 * 8; // reduces blocks to a legal multiple + if (debug) + System.out.printf ("Blocks : %,d%n", blocks); + // } this.sectorSize = 512; this.trackSize = 8 * sectorSize; @@ -146,7 +148,7 @@ public class AppleDisk implements Disk this.trackSize = sectors * sectorSize; } } - else if (pos > 0 && name.substring (pos + 1).equalsIgnoreCase ("HDV")) + else if (suffix.equalsIgnoreCase ("HDV")) { this.blocks = (int) path.length () / 4096 * 8; // reduces blocks to a legal multiple this.sectorSize = 512; @@ -154,9 +156,18 @@ public class AppleDisk implements Disk } else { - this.blocks = tracks * sectors; - this.sectorSize = (int) path.length () / blocks; - this.trackSize = sectors * sectorSize; + if (path.length () == 143360 && tracks == 256 && sectors == 8) // wiz4 + { + this.blocks = tracks * sectors; + this.sectorSize = 512; + this.trackSize = sectors * sectorSize; + } + else + { + this.blocks = tracks * sectors; + this.sectorSize = (int) path.length () / blocks; + this.trackSize = sectors * sectorSize; + } } if (false) @@ -227,12 +238,16 @@ public class AppleDisk implements Disk private void checkSectorsForData () { + if (true) + { + checkSectorsFaster (); + return; + } // force blockList to be rebuilt with the correct number/size of blocks blockList = null; - for (DiskAddress da : this) + for (DiskAddress da : this) // uses blockList.iterator { - // System.out.println (da); byte[] buffer = readSector (da); hasData[da.getBlock ()] = false; for (int i = 0; i < sectorSize; i++) @@ -244,6 +259,35 @@ public class AppleDisk implements Disk } } + private void checkSectorsFaster () + { + // force blockList to be rebuilt with the correct number/size of blocks + blockList = null; + + for (DiskAddress da : this) // uses blockList.iterator + { + if (sectorSize == SECTOR_SIZE) + { + int diskOffset = getBufferOffset (da); + hasData[da.getBlock ()] = check (diskOffset); + } + else + { + int diskOffset1 = getBufferOffset (da, 0); + int diskOffset2 = getBufferOffset (da, 1); + hasData[da.getBlock ()] = check (diskOffset1) || check (diskOffset2); + } + } + } + + private boolean check (int diskOffset) + { + for (int i = diskOffset, max = diskOffset + SECTOR_SIZE; i < max; i++) + if (diskBuffer[i] != emptyByte) + return true; + return false; + } + /* * Routines that implement the Disk interface */ @@ -362,7 +406,7 @@ public class AppleDisk implements Disk @Override public void setBlockSize (int size) { - assert (size == 256 || size == 512) : "Invalid sector size : " + size; + assert (size == SECTOR_SIZE || size == BLOCK_SIZE) : "Invalid sector size : " + size; if (sectorSize == size) return; @@ -380,11 +424,9 @@ public class AppleDisk implements Disk @Override public DiskAddress getDiskAddress (int block) { - // assert (isValidAddress (block)) : "Invalid address : " + block; if (!isValidAddress (block)) { System.out.println ("Invalid block : " + block); - // assert false; return null; // return new AppleDiskAddress (this, 0); this was looping 26/07/2016 } @@ -450,28 +492,43 @@ public class AppleDisk implements Disk } assert da.getDisk () == this : "Disk address not applicable to this disk"; - assert sectorSize == 256 || sectorSize == 512 : "Invalid sector size : " + sectorSize; + assert sectorSize == SECTOR_SIZE + || sectorSize == BLOCK_SIZE : "Invalid sector size : " + sectorSize; assert interleave >= 0 && interleave <= MAX_INTERLEAVE : "Invalid interleave : " + interleave; - if (sectorSize == 256) + if (sectorSize == SECTOR_SIZE) { - int diskOffset = da.getTrack () * trackSize - + interleaveSector[interleave][da.getSector ()] * sectorSize; - System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset, sectorSize); + int diskOffset = getBufferOffset (da); + System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset, SECTOR_SIZE); } - else if (sectorSize == 512) + else { - int diskOffset = da.getTrack () * trackSize - + interleaveSector[interleave][da.getSector () * 2] * 256; - System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset, 256); + int diskOffset = getBufferOffset (da, 0); + System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset, SECTOR_SIZE); - diskOffset = da.getTrack () * trackSize - + interleaveSector[interleave][da.getSector () * 2 + 1] * 256; - System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset + 256, 256); + diskOffset = getBufferOffset (da, 1); + System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset + SECTOR_SIZE, + SECTOR_SIZE); } } + private int getBufferOffset (DiskAddress da) + { + assert sectorSize == SECTOR_SIZE; + return da.getTrack () * trackSize + + interleaveSector[interleave][da.getSector ()] * SECTOR_SIZE; + } + + private int getBufferOffset (DiskAddress da, int seq) + { + assert sectorSize == BLOCK_SIZE; + assert seq == 0 || seq == 1; + + return da.getTrack () * trackSize + + interleaveSector[interleave][da.getSector () * 2 + seq] * SECTOR_SIZE; + } + @Override public void addActionListener (ActionListener actionListener) { diff --git a/src/com/bytezone/diskbrowser/disk/DiskFactory.java b/src/com/bytezone/diskbrowser/disk/DiskFactory.java index a7fe6b0..79828df 100755 --- a/src/com/bytezone/diskbrowser/disk/DiskFactory.java +++ b/src/com/bytezone/diskbrowser/disk/DiskFactory.java @@ -16,6 +16,7 @@ import com.bytezone.diskbrowser.pascal.PascalDisk; import com.bytezone.diskbrowser.prodos.ProdosDisk; import com.bytezone.diskbrowser.utilities.FileFormatException; import com.bytezone.diskbrowser.utilities.NuFX; +import com.bytezone.diskbrowser.wizardry.Wizardry4BootDisk; import com.bytezone.diskbrowser.wizardry.WizardryScenarioDisk; public class DiskFactory @@ -156,7 +157,7 @@ public class DiskFactory if (length != 143360 && length != 116480) { System.out.printf ("%s: invalid file length : %,d%n", file.getName (), - file.length ()); + file.length ()); return null; } @@ -248,8 +249,8 @@ public class DiskFactory disk = new DataDisk (new AppleDisk (file, 35, 16)); if (debug) - System.out.println ("Factory creating disk : " - + disk.getDisk ().getFile ().getAbsolutePath ()); + System.out.println ( + "Factory creating disk : " + disk.getDisk ().getFile ().getAbsolutePath ()); if (disk != null && compressed) disk.setOriginalPath (p); @@ -372,16 +373,53 @@ public class DiskFactory { if (debug) System.out.println ("Checking Pascal disk"); + AppleDisk disk = new AppleDisk (file, 35, 8); + if (!PascalDisk.isCorrectFormat (disk, debug)) return null; + if (debug) System.out.println ("Pascal disk OK - Checking Wizardry disk"); + if (WizardryScenarioDisk.isWizardryFormat (disk, debug)) return new WizardryScenarioDisk (disk); + if (debug) - System.out.println ("Not a Wizardry disk"); - return new PascalDisk (disk); + System.out.println ("Not a Wizardry 1-3 disk"); + + if (Wizardry4BootDisk.isWizardryIV (disk, debug)) + { + // collect 4 data disks + AppleDisk[] disks = new AppleDisk[5]; + AppleDisk d = new AppleDisk (file, 256, 8); + d.setInterleave (1); + disks[0] = d; + + for (int i = 2; i <= 5; i++) + { + String filename = file.getAbsolutePath ().replace ("1.dsk", i + ".dsk"); + File f = new File (filename); + if (f.exists () && f.isFile ()) + { + AppleDisk dataDisk = new AppleDisk (f, 35, 8); + dataDisk.setInterleave (1); + disks[i - 1] = dataDisk; + } + else + { + PascalDisk pascalDisk = new PascalDisk (disk); + return pascalDisk; + } + } + Wizardry4BootDisk wiz4 = new Wizardry4BootDisk (disks); + return wiz4; + } + if (debug) + System.out.println ("Not a Wizardry IV disk"); + + PascalDisk pascalDisk = new PascalDisk (disk); + return pascalDisk; } private static InfocomDisk checkInfocomDisk (File file) diff --git a/src/com/bytezone/diskbrowser/disk/DualDosDisk.java b/src/com/bytezone/diskbrowser/disk/DualDosDisk.java index 689bde6..4220717 100755 --- a/src/com/bytezone/diskbrowser/disk/DualDosDisk.java +++ b/src/com/bytezone/diskbrowser/disk/DualDosDisk.java @@ -11,12 +11,10 @@ import javax.swing.tree.DefaultTreeModel; import com.bytezone.diskbrowser.applefile.AbstractFile; import com.bytezone.diskbrowser.applefile.AppleFileSource; import com.bytezone.diskbrowser.gui.DataSource; -import com.bytezone.diskbrowser.gui.FileSelectedEvent; -import com.bytezone.diskbrowser.gui.FileSelectionListener; // Apple Assembly Lines disks are dual-dos -public class DualDosDisk implements FormattedDisk, FileSelectionListener +public class DualDosDisk implements FormattedDisk { private final FormattedDisk[] disks = new FormattedDisk[2]; private int currentDisk; @@ -25,16 +23,21 @@ public class DualDosDisk implements FormattedDisk, FileSelectionListener public DualDosDisk (FormattedDisk disk0, FormattedDisk disk1) { String diskName = disk0.getDisk ().getFile ().getName (); - String text = "This disk contains both DOS and Prodos files. Isn't that clever?\n\n" - + disk0.getDisk () + "\n" + disk1.getDisk (); - DefaultMutableTreeNode root = - new DefaultMutableTreeNode (new DefaultAppleFileSource (diskName, text, this)); + String text = "This disk contains both DOS and Prodos files\n\n" + disk0.getDisk () + + "\n" + disk1.getDisk (); + + DefaultAppleFileSource dafs = new DefaultAppleFileSource (diskName, text, this); + DefaultMutableTreeNode root = new DefaultMutableTreeNode (dafs); + DefaultTreeModel treeModel = new DefaultTreeModel (root); tree = new JTree (treeModel); - treeModel.setAsksAllowsChildren (true); // allows empty nodes to appear as folders + + // allow empty nodes to appear as folders + treeModel.setAsksAllowsChildren (true); this.disks[0] = disk0; this.disks[1] = disk1; + disk0.setParent (this); disk1.setParent (this); @@ -110,15 +113,11 @@ public class DualDosDisk implements FormattedDisk, FileSelectionListener currentDisk = 0; else if (disks[1] == fd && currentDisk != 1) currentDisk = 1; - - // System.out.println ("AFS : " + afs); - // System.out.println ("1. Setting current disk to : " + currentDisk); } public void setCurrentDiskNo (int n) { currentDisk = n; - // System.out.println ("2. Setting current disk to : " + currentDisk); } public int getCurrentDiskNo () @@ -149,19 +148,7 @@ public class DualDosDisk implements FormattedDisk, FileSelectionListener @Override public AppleFileSource getFile (String uniqueName) { - if (true) - return disks[currentDisk].getFile (uniqueName); - // System.out.println ("Searching for : " + uniqueName); - for (int i = 0; i < 2; i++) - { - AppleFileSource afs = disks[i].getFile (uniqueName); - if (afs != null) - { - setCurrentDiskNo (i); - return afs; - } - } - return null; + return disks[currentDisk].getFile (uniqueName); } @Override @@ -254,12 +241,6 @@ public class DualDosDisk implements FormattedDisk, FileSelectionListener disks[currentDisk].setParent (disk); } - @Override - public void fileSelected (FileSelectedEvent event) - { - System.out.println ("In DDD - file selected : " + event.file); - } - @Override public String getSectorFilename (DiskAddress da) { diff --git a/src/com/bytezone/diskbrowser/pascal/FileEntry.java b/src/com/bytezone/diskbrowser/pascal/FileEntry.java index 598338e..5e246d4 100644 --- a/src/com/bytezone/diskbrowser/pascal/FileEntry.java +++ b/src/com/bytezone/diskbrowser/pascal/FileEntry.java @@ -4,7 +4,7 @@ import com.bytezone.diskbrowser.applefile.*; import com.bytezone.diskbrowser.utilities.FileFormatException; import com.bytezone.diskbrowser.utilities.HexFormatter; -class FileEntry extends CatalogEntry +public class FileEntry extends CatalogEntry { int bytesUsedInLastBlock; private final Relocator relocator; diff --git a/src/com/bytezone/diskbrowser/pascal/PascalCodeObject.java b/src/com/bytezone/diskbrowser/pascal/PascalCodeObject.java index 84ba66f..e95c946 100644 --- a/src/com/bytezone/diskbrowser/pascal/PascalCodeObject.java +++ b/src/com/bytezone/diskbrowser/pascal/PascalCodeObject.java @@ -26,7 +26,8 @@ class PascalCodeObject implements AppleFileSource int lo = firstBlock + segment.blockNo; int hi = lo + (segment.size - 1) / 512; Disk disk = parent.getDisk (); - for (int i = lo; i <= hi; i++) + int max = Math.min (hi, 279); + for (int i = lo; i <= max; i++) blocks.add (disk.getDiskAddress (i)); } diff --git a/src/com/bytezone/diskbrowser/pascal/PascalDisk.java b/src/com/bytezone/diskbrowser/pascal/PascalDisk.java index d43ded9..01ff5a7 100755 --- a/src/com/bytezone/diskbrowser/pascal/PascalDisk.java +++ b/src/com/bytezone/diskbrowser/pascal/PascalDisk.java @@ -23,7 +23,7 @@ public class PascalDisk extends AbstractFormattedDisk private final DateFormat df = DateFormat.getDateInstance (DateFormat.SHORT); private final VolumeEntry volumeEntry; private final PascalCatalogSector diskCatalogSector; - private Relocator relocator; + protected Relocator relocator; final String[] fileTypes = { "Volume", "Xdsk", "Code", "Text", "Info", "Data", "Graf", "Foto", "SecureDir" }; @@ -41,6 +41,7 @@ public class PascalDisk extends AbstractFormattedDisk { super (disk); + System.out.println (disk.getTotalBlocks ()); sectorTypesList.add (diskBootSector); sectorTypesList.add (catalogSector); sectorTypesList.add (dataSector); @@ -50,9 +51,8 @@ public class PascalDisk extends AbstractFormattedDisk sectorTypesList.add (grafSector); sectorTypesList.add (fotoSector); - // DiskAddress da = disk.getDiskAddress (0); - List blocks = disk.getDiskAddressList (0, 1); - this.bootSector = new BootSector (disk, disk.readSectors (blocks), "Pascal");//, blocks); + List blocks = disk.getDiskAddressList (0, 1); // B0, B1 + this.bootSector = new BootSector (disk, disk.readSectors (blocks), "Pascal"); byte[] buffer = disk.readSector (2); byte[] data = new byte[CATALOG_ENTRY_SIZE]; @@ -67,7 +67,7 @@ public class PascalDisk extends AbstractFormattedDisk freeBlocks.set (i, false); } - for (int i = 2; i < 280; i++) + for (int i = 2; i < disk.getTotalBlocks (); i++) freeBlocks.set (i, true); List sectors = new ArrayList (); @@ -143,18 +143,11 @@ public class PascalDisk extends AbstractFormattedDisk if (checkFormat (disk, debug)) return true; return false; - // disk.setInterleave (0); - // if (checkFormat (disk, debug)) - // return true; - // disk.setInterleave (3); - // return checkFormat (disk, debug); } public static boolean checkFormat (AppleDisk disk, boolean debug) { byte[] buffer = disk.readSector (2); - // if (debug) - // System.out.println (HexFormatter.format (buffer)); int nameLength = HexFormatter.intValue (buffer[6]); if (nameLength < 1 || nameLength > 7) { diff --git a/src/com/bytezone/diskbrowser/utilities/Utility.java b/src/com/bytezone/diskbrowser/utilities/Utility.java index d2cbf99..ff849b9 100644 --- a/src/com/bytezone/diskbrowser/utilities/Utility.java +++ b/src/com/bytezone/diskbrowser/utilities/Utility.java @@ -42,19 +42,13 @@ public class Utility } } - private static boolean matches (byte[] buffer, int offset, byte[] key) + public static boolean matches (byte[] buffer, int offset, byte[] key) { int ptr = 0; while (offset < buffer.length && ptr < key.length) - { if (buffer[offset++] != key[ptr++]) - { - // System.out.printf ("%04X: %02X != %02X%n", offset, buffer[offset], key[ptr]); return false; - } - // System.out.printf ("%04X: %02X == %02X%n", offset, buffer[offset - 1], - // key[ptr - 1]); - } + return true; } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/wizardry/Wizardry4BootDisk.java b/src/com/bytezone/diskbrowser/wizardry/Wizardry4BootDisk.java new file mode 100644 index 0000000..caa975d --- /dev/null +++ b/src/com/bytezone/diskbrowser/wizardry/Wizardry4BootDisk.java @@ -0,0 +1,37 @@ +package com.bytezone.diskbrowser.wizardry; + +import java.util.ArrayList; +import java.util.List; + +import com.bytezone.diskbrowser.disk.AppleDisk; +import com.bytezone.diskbrowser.disk.Disk; +import com.bytezone.diskbrowser.pascal.PascalDisk; +import com.bytezone.diskbrowser.utilities.Utility; + +public class Wizardry4BootDisk extends PascalDisk +{ + List disks = new ArrayList (); + + public Wizardry4BootDisk (AppleDisk[] dataDisks) + { + super (dataDisks[0]); + + for (AppleDisk dataDisk : dataDisks) + relocator.addDisk (dataDisk); + } + + public static boolean isWizardryIV (Disk disk, boolean debug) + { + byte[] header = { 0x00, (byte) 0xEA, (byte) 0xA9, 0x60, (byte) 0x8D, 0x01, 0x08 }; + byte[] buffer = disk.readSector (0); + + if (!Utility.matches (buffer, 0, header)) + return false; + buffer = disk.readSector (1); + + if (buffer[510] != 1) + return false; + + return true; + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java b/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java index a541a44..44a19ce 100755 --- a/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java +++ b/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java @@ -9,7 +9,11 @@ import javax.swing.tree.DefaultTreeModel; import com.bytezone.diskbrowser.applefile.AbstractFile; import com.bytezone.diskbrowser.applefile.AppleFileSource; -import com.bytezone.diskbrowser.disk.*; +import com.bytezone.diskbrowser.disk.DefaultAppleFileSource; +import com.bytezone.diskbrowser.disk.DefaultDataSource; +import com.bytezone.diskbrowser.disk.Disk; +import com.bytezone.diskbrowser.disk.DiskAddress; +import com.bytezone.diskbrowser.disk.SectorType; import com.bytezone.diskbrowser.gui.DataSource; import com.bytezone.diskbrowser.pascal.PascalDisk; import com.bytezone.diskbrowser.utilities.HexFormatter; @@ -93,7 +97,8 @@ public class WizardryScenarioDisk extends PascalDisk extractMonsters (linkNode ("Monsters", "Monsters string", dataNode), sectors); extractCharacters (linkNode ("Characters", "Characters string", dataNode), sectors); extractImages (linkNode ("Images", "Images string", dataNode), sectors); - extractExperienceLevels (linkNode ("Experience", "Experience string", dataNode), sectors); + extractExperienceLevels (linkNode ("Experience", "Experience string", dataNode), + sectors); // node = linkNode ("Spells", "Spells string", dataNode); node = null; extractSpells (node, sectors); @@ -112,7 +117,7 @@ public class WizardryScenarioDisk extends PascalDisk } private DefaultMutableTreeNode linkNode (String name, String text, - DefaultMutableTreeNode parent) + DefaultMutableTreeNode parent) { DefaultAppleFileSource afs = new DefaultAppleFileSource (name, text, this); DefaultMutableTreeNode node = new DefaultMutableTreeNode (afs); @@ -131,7 +136,7 @@ public class WizardryScenarioDisk extends PascalDisk { String text = HexFormatter.getPascalString (buffer, ptr); if (!text.equals ("SCENARIO.DATA") && !text.equals ("SCENARIO.MESGS") - && !text.equals ("WIZARDRY.CODE")) + && !text.equals ("WIZARDRY.CODE")) return false; } return true; @@ -187,8 +192,8 @@ public class WizardryScenarioDisk extends PascalDisk dds.text = text.toString (); } - private int addReward (byte[] buffer, List blocks, DefaultMutableTreeNode node, - int seq) + private int addReward (byte[] buffer, List blocks, + DefaultMutableTreeNode node, int seq) { int recLen = 168; for (int ptr = 0; ptr < 1008; ptr += recLen) @@ -222,20 +227,20 @@ public class WizardryScenarioDisk extends PascalDisk StringBuilder text = new StringBuilder (); text.append ("Name Age Align Race Type " - + "HP St In Pi Vi Ag Lu Status\n"); + + "HP St In Pi Vi Ag Lu Status\n"); text.append ("------------- ---- -------- -------- ---------- " - + "-- -- -- -- -- -- -- ------\n"); + + "-- -- -- -- -- -- -- ------\n"); for (Character ch : characters) { Statistics stats = ch.getStatistics (); Attributes att = ch.getAttributes (); - text.append (String.format ("%-15s %2d %-8s %-8s %-8s %3d", ch, - (stats.ageInWeeks / 52), stats.alignment, stats.race, - stats.type, stats.hitsMax)); + text.append ( + String.format ("%-15s %2d %-8s %-8s %-8s %3d", ch, (stats.ageInWeeks / 52), + stats.alignment, stats.race, stats.type, stats.hitsMax)); text.append (String.format (" %2d %2d %2d %2d %2d %2d", att.strength, - att.intelligence, att.piety, att.vitality, att.agility, - att.luck)); - text.append (String.format (" %5s %s%n", stats.status, ch.isOut () ? "* OUT *" : "")); + att.intelligence, att.piety, att.vitality, att.agility, att.luck)); + text.append ( + String.format (" %5s %s%n", stats.status, ch.isOut () ? "* OUT *" : "")); } DefaultAppleFileSource afs = (DefaultAppleFileSource) node.getUserObject (); @@ -245,7 +250,7 @@ public class WizardryScenarioDisk extends PascalDisk } private void addCharacters (byte[] buffer, List blocks, - DefaultMutableTreeNode node) + DefaultMutableTreeNode node) { int recLen = 208; for (int ptr = 0; ptr < 832; ptr += recLen) @@ -298,7 +303,7 @@ public class WizardryScenarioDisk extends PascalDisk } private void addMonsters (byte[] buffer, List blocks, - DefaultMutableTreeNode node) + DefaultMutableTreeNode node) { int recLen = 158; for (int ptr = 0; ptr < 948; ptr += recLen) @@ -350,7 +355,8 @@ public class WizardryScenarioDisk extends PascalDisk dds.text = text.toString (); } - private void addItems (byte[] buffer, List blocks, DefaultMutableTreeNode node) + private void addItems (byte[] buffer, List blocks, + DefaultMutableTreeNode node) { int recLen = 78; for (int ptr = 0; ptr < 1014; ptr += recLen) @@ -523,7 +529,7 @@ public class WizardryScenarioDisk extends PascalDisk } AbstractImage mi = scenarioHeader.scenarioID < 3 ? new Image (name, buffer) - : new ImageV2 (name, exactBuffer); + : new ImageV2 (name, exactBuffer); images.add (mi); addToNode (mi, node, da, imageSector); } @@ -538,7 +544,8 @@ public class WizardryScenarioDisk extends PascalDisk dds.text = text.toString (); } - private void extractExperienceLevels (DefaultMutableTreeNode node, List sectors) + private void extractExperienceLevels (DefaultMutableTreeNode node, + List sectors) { List nodeSectors = new ArrayList (); ScenarioData sd = scenarioHeader.data.get (Header.EXPERIENCE_AREA); @@ -569,7 +576,7 @@ public class WizardryScenarioDisk extends PascalDisk } private void addToNode (AbstractFile af, DefaultMutableTreeNode node, DiskAddress block, - SectorType type) + SectorType type) { ArrayList blocks = new ArrayList (1); blocks.add (block); @@ -577,15 +584,17 @@ public class WizardryScenarioDisk extends PascalDisk } private void addToNode (AbstractFile af, DefaultMutableTreeNode node, - List blocks, SectorType type) + List blocks, SectorType type) { - DefaultAppleFileSource dafs = new DefaultAppleFileSource (af.getName (), af, this, blocks); + DefaultAppleFileSource dafs = + new DefaultAppleFileSource (af.getName (), af, this, blocks); DefaultMutableTreeNode childNode = new DefaultMutableTreeNode (dafs); node.add (childNode); childNode.setAllowsChildren (false); } - private List getTwoBlocks (ScenarioData sd, int i, List sectors) + private List getTwoBlocks (ScenarioData sd, int i, + List sectors) { ArrayList blocks = new ArrayList (2); blocks.add (sectors.get (sd.dataOffset + i * 2));