Allow pascal disks >280 blocks

This commit is contained in:
Denis Molony 2016-08-08 14:53:29 +10:00
parent 1562413ea2
commit 144c8e2e69
11 changed files with 328 additions and 130 deletions

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import com.bytezone.diskbrowser.disk.AppleDisk;
import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.HexFormatter;
public class Relocator extends AbstractFile public class Relocator extends AbstractFile
@ -15,6 +16,12 @@ public class Relocator extends AbstractFile
private final List<MultiDiskAddress> newAddresses = new ArrayList<MultiDiskAddress> (); private final List<MultiDiskAddress> newAddresses = new ArrayList<MultiDiskAddress> ();
private final List<MultiDiskAddress> oldAddresses = new ArrayList<MultiDiskAddress> (); private final List<MultiDiskAddress> oldAddresses = new ArrayList<MultiDiskAddress> ();
private final List<MultiDiskAddress> logicalAddresses =
new ArrayList<MultiDiskAddress> ();
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) public Relocator (String name, byte[] buffer)
{ {
super (name, buffer); super (name, buffer);
@ -30,11 +37,16 @@ public class Relocator extends AbstractFile
ptr += diskRecord.size (); ptr += diskRecord.size ();
} }
logicalAddresses.add (new MultiDiskAddress (0, 0, 0, 0x800));
for (DiskRecord diskRecord : diskRecords) for (DiskRecord diskRecord : diskRecords)
for (DiskSegment diskSegment : diskRecord.diskSegments) for (DiskSegment diskSegment : diskRecord.diskSegments)
{
addresses addresses
.add (new MultiDiskAddress (diskRecord.diskNumber, diskSegment.logicalBlock, .add (new MultiDiskAddress (diskRecord.diskNumber, diskSegment.logicalBlock,
diskSegment.physicalBlock, diskSegment.segmentLength)); diskSegment.physicalBlock, diskSegment.segmentLength));
addLogicalBlock ((byte) diskRecord.diskNumber, diskSegment);
}
getMultiDiskAddress ("BOOT", 0, 2); getMultiDiskAddress ("BOOT", 0, 2);
getMultiDiskAddress ("CATALOG", 2, 4); getMultiDiskAddress ("CATALOG", 2, 4);
@ -48,6 +60,18 @@ public class Relocator extends AbstractFile
multiDiskAddress.totalBlocks, multiDiskAddress.name); 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<MultiDiskAddress> getMultiDiskAddress (String name, int blockNumber, public List<MultiDiskAddress> getMultiDiskAddress (String name, int blockNumber,
int length) int length)
{ {
@ -93,6 +117,22 @@ public class Relocator extends AbstractFile
return foundAddresses; 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 @Override
public String getText () public String getText ()
{ {
@ -115,7 +155,7 @@ public class Relocator extends AbstractFile
previousDiskNumber = multiDiskAddress.diskNumber; previousDiskNumber = multiDiskAddress.diskNumber;
text.append ("\n"); text.append ("\n");
text.append ("Disk Logical Physical Size Name\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", text.append (String.format (" %d %03X %03X %03X %s%n",
multiDiskAddress.diskNumber, multiDiskAddress.logicalBlockNumber, multiDiskAddress.diskNumber, multiDiskAddress.logicalBlockNumber,
@ -123,6 +163,36 @@ public class Relocator extends AbstractFile
multiDiskAddress.name)); 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 (); 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 ("Disk number.... %04X%n", diskNumber));
text.append (String.format ("Segments....... %04X%n%n", totDiskSegments)); 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 count = 1;
int last = 0;
int size = 0;
for (DiskSegment segment : diskSegments) 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 (); return text.toString ();
} }
@ -183,20 +266,21 @@ public class Relocator extends AbstractFile
@Override @Override
public String toString () public String toString ()
{ {
return String.format (" %04X %04X %04X", logicalBlock, physicalBlock, return String.format (" %04X %04X - %04X %04X - %04X", segmentLength,
segmentLength); logicalBlock, (logicalBlock + segmentLength - 1), physicalBlock,
(physicalBlock + segmentLength - 1));
} }
public String toString (int offset) // public String toString (int offset)
{ // {
int logical = logicalBlock - offset; // int logical = logicalBlock - offset;
int physical = physicalBlock - offset; // int physical = physicalBlock - offset;
if (physical >= 0) // if (physical >= 0)
return String.format (" %04X %04X %04X %04X %04X", // return String.format (" %04X %04X %04X %04X %04X",
logicalBlock, physicalBlock, segmentLength, logical, physical); // logicalBlock, physicalBlock, segmentLength, logical, physical);
return String.format (" %04X %04X %04X", logicalBlock, physicalBlock, // return String.format (" %04X %04X %04X", logicalBlock, physicalBlock,
segmentLength); // segmentLength);
} // }
} }
class MultiDiskAddress implements Comparable<MultiDiskAddress> class MultiDiskAddress implements Comparable<MultiDiskAddress>

View File

@ -95,7 +95,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
protected void setEmptyByte (byte value) protected void setEmptyByte (byte value)
{ {
getDisk ().setEmptyByte ((byte) 0xE5); getDisk ().setEmptyByte (value);
setSectorTypes (); setSectorTypes ();
} }
@ -130,6 +130,10 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
gridLayout = new Dimension (16, 100); gridLayout = new Dimension (16, 100);
break; break;
case 2048:
gridLayout = new Dimension (8, 256);
break;
default: default:
int[] sizes = { 32, 20, 16, 8 }; int[] sizes = { 32, 20, 16, 8 };
for (int size : sizes) for (int size : sizes)
@ -237,8 +241,8 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
public void makeNodeVisible (DefaultMutableTreeNode node) public void makeNodeVisible (DefaultMutableTreeNode node)
{ {
catalogTree.makeVisible (new TreePath ( catalogTree.makeVisible (
((DefaultTreeModel) catalogTree.getModel ()).getPathToRoot (node))); new TreePath (((DefaultTreeModel) catalogTree.getModel ()).getPathToRoot (node)));
} }
protected DefaultMutableTreeNode findNode (DefaultMutableTreeNode node, String name) protected DefaultMutableTreeNode findNode (DefaultMutableTreeNode node, String name)

View File

@ -20,8 +20,10 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
public class AppleDisk implements Disk public class AppleDisk implements Disk
{ {
static final String newLine = String.format ("%n"); private static final String newLine = String.format ("%n");
static final int MAX_INTERLEAVE = 3; 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; public final File path;
private final byte[] diskBuffer; // contains the disk contents in memory private final byte[] diskBuffer; // contains the disk contents in memory
@ -89,13 +91,13 @@ public class AppleDisk implements Disk
String name = path.getName (); String name = path.getName ();
int pos = name.lastIndexOf ('.'); int pos = name.lastIndexOf ('.');
String suffix = pos > 0 ? name.substring (pos + 1) : "";
byte[] buffer = getPrefix (path); // HDV could be a 2mg byte[] buffer = getPrefix (path); // HDV could be a 2mg
String prefix = new String (buffer, 0, 4); String prefix = new String (buffer, 0, 4);
int skip = 0; int skip = 0;
if ((pos > 0 && name.substring (pos + 1).equalsIgnoreCase ("2mg")) if (suffix.equalsIgnoreCase ("2mg") || "2IMG".equals (prefix))
|| "2IMG".equals (prefix))
// if ("2IMG".equals (prefix))
{ {
if (debug) if (debug)
System.out.println (Utility.toHex (buffer)); System.out.println (Utility.toHex (buffer));
@ -125,11 +127,11 @@ public class AppleDisk implements Disk
// int format = buffer[12] & 0xFF; // int format = buffer[12] & 0xFF;
// if (blocks == 0 && format == 1) // if (blocks == 0 && format == 1)
{ // {
this.blocks = diskData / 4096 * 8; // reduces blocks to a legal multiple this.blocks = diskData / 4096 * 8; // reduces blocks to a legal multiple
if (debug) if (debug)
System.out.printf ("Blocks : %,d%n", blocks); System.out.printf ("Blocks : %,d%n", blocks);
} // }
this.sectorSize = 512; this.sectorSize = 512;
this.trackSize = 8 * sectorSize; this.trackSize = 8 * sectorSize;
@ -146,7 +148,7 @@ public class AppleDisk implements Disk
this.trackSize = sectors * sectorSize; 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.blocks = (int) path.length () / 4096 * 8; // reduces blocks to a legal multiple
this.sectorSize = 512; this.sectorSize = 512;
@ -154,9 +156,18 @@ public class AppleDisk implements Disk
} }
else else
{ {
this.blocks = tracks * sectors; if (path.length () == 143360 && tracks == 256 && sectors == 8) // wiz4
this.sectorSize = (int) path.length () / blocks; {
this.trackSize = sectors * sectorSize; 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) if (false)
@ -227,12 +238,16 @@ public class AppleDisk implements Disk
private void checkSectorsForData () private void checkSectorsForData ()
{ {
if (true)
{
checkSectorsFaster ();
return;
}
// force blockList to be rebuilt with the correct number/size of blocks // force blockList to be rebuilt with the correct number/size of blocks
blockList = null; blockList = null;
for (DiskAddress da : this) for (DiskAddress da : this) // uses blockList.iterator
{ {
// System.out.println (da);
byte[] buffer = readSector (da); byte[] buffer = readSector (da);
hasData[da.getBlock ()] = false; hasData[da.getBlock ()] = false;
for (int i = 0; i < sectorSize; i++) 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 * Routines that implement the Disk interface
*/ */
@ -362,7 +406,7 @@ public class AppleDisk implements Disk
@Override @Override
public void setBlockSize (int size) 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) if (sectorSize == size)
return; return;
@ -380,11 +424,9 @@ public class AppleDisk implements Disk
@Override @Override
public DiskAddress getDiskAddress (int block) public DiskAddress getDiskAddress (int block)
{ {
// assert (isValidAddress (block)) : "Invalid address : " + block;
if (!isValidAddress (block)) if (!isValidAddress (block))
{ {
System.out.println ("Invalid block : " + block); System.out.println ("Invalid block : " + block);
// assert false;
return null; return null;
// return new AppleDiskAddress (this, 0); this was looping 26/07/2016 // 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 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 : " assert interleave >= 0 && interleave <= MAX_INTERLEAVE : "Invalid interleave : "
+ interleave; + interleave;
if (sectorSize == 256) if (sectorSize == SECTOR_SIZE)
{ {
int diskOffset = da.getTrack () * trackSize int diskOffset = getBufferOffset (da);
+ interleaveSector[interleave][da.getSector ()] * sectorSize; System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset, SECTOR_SIZE);
System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset, sectorSize);
} }
else if (sectorSize == 512) else
{ {
int diskOffset = da.getTrack () * trackSize int diskOffset = getBufferOffset (da, 0);
+ interleaveSector[interleave][da.getSector () * 2] * 256; System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset, SECTOR_SIZE);
System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset, 256);
diskOffset = da.getTrack () * trackSize diskOffset = getBufferOffset (da, 1);
+ interleaveSector[interleave][da.getSector () * 2 + 1] * 256; System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset + SECTOR_SIZE,
System.arraycopy (diskBuffer, diskOffset, buffer, bufferOffset + 256, 256); 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 @Override
public void addActionListener (ActionListener actionListener) public void addActionListener (ActionListener actionListener)
{ {

View File

@ -16,6 +16,7 @@ import com.bytezone.diskbrowser.pascal.PascalDisk;
import com.bytezone.diskbrowser.prodos.ProdosDisk; import com.bytezone.diskbrowser.prodos.ProdosDisk;
import com.bytezone.diskbrowser.utilities.FileFormatException; import com.bytezone.diskbrowser.utilities.FileFormatException;
import com.bytezone.diskbrowser.utilities.NuFX; import com.bytezone.diskbrowser.utilities.NuFX;
import com.bytezone.diskbrowser.wizardry.Wizardry4BootDisk;
import com.bytezone.diskbrowser.wizardry.WizardryScenarioDisk; import com.bytezone.diskbrowser.wizardry.WizardryScenarioDisk;
public class DiskFactory public class DiskFactory
@ -156,7 +157,7 @@ public class DiskFactory
if (length != 143360 && length != 116480) if (length != 143360 && length != 116480)
{ {
System.out.printf ("%s: invalid file length : %,d%n", file.getName (), System.out.printf ("%s: invalid file length : %,d%n", file.getName (),
file.length ()); file.length ());
return null; return null;
} }
@ -248,8 +249,8 @@ public class DiskFactory
disk = new DataDisk (new AppleDisk (file, 35, 16)); disk = new DataDisk (new AppleDisk (file, 35, 16));
if (debug) if (debug)
System.out.println ("Factory creating disk : " System.out.println (
+ disk.getDisk ().getFile ().getAbsolutePath ()); "Factory creating disk : " + disk.getDisk ().getFile ().getAbsolutePath ());
if (disk != null && compressed) if (disk != null && compressed)
disk.setOriginalPath (p); disk.setOriginalPath (p);
@ -372,16 +373,53 @@ public class DiskFactory
{ {
if (debug) if (debug)
System.out.println ("Checking Pascal disk"); System.out.println ("Checking Pascal disk");
AppleDisk disk = new AppleDisk (file, 35, 8); AppleDisk disk = new AppleDisk (file, 35, 8);
if (!PascalDisk.isCorrectFormat (disk, debug)) if (!PascalDisk.isCorrectFormat (disk, debug))
return null; return null;
if (debug) if (debug)
System.out.println ("Pascal disk OK - Checking Wizardry disk"); System.out.println ("Pascal disk OK - Checking Wizardry disk");
if (WizardryScenarioDisk.isWizardryFormat (disk, debug)) if (WizardryScenarioDisk.isWizardryFormat (disk, debug))
return new WizardryScenarioDisk (disk); return new WizardryScenarioDisk (disk);
if (debug) if (debug)
System.out.println ("Not a Wizardry disk"); System.out.println ("Not a Wizardry 1-3 disk");
return new PascalDisk (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) private static InfocomDisk checkInfocomDisk (File file)

View File

@ -11,12 +11,10 @@ import javax.swing.tree.DefaultTreeModel;
import com.bytezone.diskbrowser.applefile.AbstractFile; import com.bytezone.diskbrowser.applefile.AbstractFile;
import com.bytezone.diskbrowser.applefile.AppleFileSource; import com.bytezone.diskbrowser.applefile.AppleFileSource;
import com.bytezone.diskbrowser.gui.DataSource; 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 // 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 final FormattedDisk[] disks = new FormattedDisk[2];
private int currentDisk; private int currentDisk;
@ -25,16 +23,21 @@ public class DualDosDisk implements FormattedDisk, FileSelectionListener
public DualDosDisk (FormattedDisk disk0, FormattedDisk disk1) public DualDosDisk (FormattedDisk disk0, FormattedDisk disk1)
{ {
String diskName = disk0.getDisk ().getFile ().getName (); String diskName = disk0.getDisk ().getFile ().getName ();
String text = "This disk contains both DOS and Prodos files. Isn't that clever?\n\n" String text = "This disk contains both DOS and Prodos files\n\n" + disk0.getDisk ()
+ disk0.getDisk () + "\n" + disk1.getDisk (); + "\n" + disk1.getDisk ();
DefaultMutableTreeNode root =
new DefaultMutableTreeNode (new DefaultAppleFileSource (diskName, text, this)); DefaultAppleFileSource dafs = new DefaultAppleFileSource (diskName, text, this);
DefaultMutableTreeNode root = new DefaultMutableTreeNode (dafs);
DefaultTreeModel treeModel = new DefaultTreeModel (root); DefaultTreeModel treeModel = new DefaultTreeModel (root);
tree = new JTree (treeModel); 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[0] = disk0;
this.disks[1] = disk1; this.disks[1] = disk1;
disk0.setParent (this); disk0.setParent (this);
disk1.setParent (this); disk1.setParent (this);
@ -110,15 +113,11 @@ public class DualDosDisk implements FormattedDisk, FileSelectionListener
currentDisk = 0; currentDisk = 0;
else if (disks[1] == fd && currentDisk != 1) else if (disks[1] == fd && currentDisk != 1)
currentDisk = 1; currentDisk = 1;
// System.out.println ("AFS : " + afs);
// System.out.println ("1. Setting current disk to : " + currentDisk);
} }
public void setCurrentDiskNo (int n) public void setCurrentDiskNo (int n)
{ {
currentDisk = n; currentDisk = n;
// System.out.println ("2. Setting current disk to : " + currentDisk);
} }
public int getCurrentDiskNo () public int getCurrentDiskNo ()
@ -149,19 +148,7 @@ public class DualDosDisk implements FormattedDisk, FileSelectionListener
@Override @Override
public AppleFileSource getFile (String uniqueName) public AppleFileSource getFile (String uniqueName)
{ {
if (true) return disks[currentDisk].getFile (uniqueName);
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;
} }
@Override @Override
@ -254,12 +241,6 @@ public class DualDosDisk implements FormattedDisk, FileSelectionListener
disks[currentDisk].setParent (disk); disks[currentDisk].setParent (disk);
} }
@Override
public void fileSelected (FileSelectedEvent event)
{
System.out.println ("In DDD - file selected : " + event.file);
}
@Override @Override
public String getSectorFilename (DiskAddress da) public String getSectorFilename (DiskAddress da)
{ {

View File

@ -4,7 +4,7 @@ import com.bytezone.diskbrowser.applefile.*;
import com.bytezone.diskbrowser.utilities.FileFormatException; import com.bytezone.diskbrowser.utilities.FileFormatException;
import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.HexFormatter;
class FileEntry extends CatalogEntry public class FileEntry extends CatalogEntry
{ {
int bytesUsedInLastBlock; int bytesUsedInLastBlock;
private final Relocator relocator; private final Relocator relocator;

View File

@ -26,7 +26,8 @@ class PascalCodeObject implements AppleFileSource
int lo = firstBlock + segment.blockNo; int lo = firstBlock + segment.blockNo;
int hi = lo + (segment.size - 1) / 512; int hi = lo + (segment.size - 1) / 512;
Disk disk = parent.getDisk (); 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)); blocks.add (disk.getDiskAddress (i));
} }

View File

@ -23,7 +23,7 @@ public class PascalDisk extends AbstractFormattedDisk
private final DateFormat df = DateFormat.getDateInstance (DateFormat.SHORT); private final DateFormat df = DateFormat.getDateInstance (DateFormat.SHORT);
private final VolumeEntry volumeEntry; private final VolumeEntry volumeEntry;
private final PascalCatalogSector diskCatalogSector; private final PascalCatalogSector diskCatalogSector;
private Relocator relocator; protected Relocator relocator;
final String[] fileTypes = final String[] fileTypes =
{ "Volume", "Xdsk", "Code", "Text", "Info", "Data", "Graf", "Foto", "SecureDir" }; { "Volume", "Xdsk", "Code", "Text", "Info", "Data", "Graf", "Foto", "SecureDir" };
@ -41,6 +41,7 @@ public class PascalDisk extends AbstractFormattedDisk
{ {
super (disk); super (disk);
System.out.println (disk.getTotalBlocks ());
sectorTypesList.add (diskBootSector); sectorTypesList.add (diskBootSector);
sectorTypesList.add (catalogSector); sectorTypesList.add (catalogSector);
sectorTypesList.add (dataSector); sectorTypesList.add (dataSector);
@ -50,9 +51,8 @@ public class PascalDisk extends AbstractFormattedDisk
sectorTypesList.add (grafSector); sectorTypesList.add (grafSector);
sectorTypesList.add (fotoSector); sectorTypesList.add (fotoSector);
// DiskAddress da = disk.getDiskAddress (0); List<DiskAddress> blocks = disk.getDiskAddressList (0, 1); // B0, B1
List<DiskAddress> blocks = disk.getDiskAddressList (0, 1); this.bootSector = new BootSector (disk, disk.readSectors (blocks), "Pascal");
this.bootSector = new BootSector (disk, disk.readSectors (blocks), "Pascal");//, blocks);
byte[] buffer = disk.readSector (2); byte[] buffer = disk.readSector (2);
byte[] data = new byte[CATALOG_ENTRY_SIZE]; byte[] data = new byte[CATALOG_ENTRY_SIZE];
@ -67,7 +67,7 @@ public class PascalDisk extends AbstractFormattedDisk
freeBlocks.set (i, false); freeBlocks.set (i, false);
} }
for (int i = 2; i < 280; i++) for (int i = 2; i < disk.getTotalBlocks (); i++)
freeBlocks.set (i, true); freeBlocks.set (i, true);
List<DiskAddress> sectors = new ArrayList<DiskAddress> (); List<DiskAddress> sectors = new ArrayList<DiskAddress> ();
@ -143,18 +143,11 @@ public class PascalDisk extends AbstractFormattedDisk
if (checkFormat (disk, debug)) if (checkFormat (disk, debug))
return true; return true;
return false; 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) public static boolean checkFormat (AppleDisk disk, boolean debug)
{ {
byte[] buffer = disk.readSector (2); byte[] buffer = disk.readSector (2);
// if (debug)
// System.out.println (HexFormatter.format (buffer));
int nameLength = HexFormatter.intValue (buffer[6]); int nameLength = HexFormatter.intValue (buffer[6]);
if (nameLength < 1 || nameLength > 7) if (nameLength < 1 || nameLength > 7)
{ {

View File

@ -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; int ptr = 0;
while (offset < buffer.length && ptr < key.length) while (offset < buffer.length && ptr < key.length)
{
if (buffer[offset++] != key[ptr++]) if (buffer[offset++] != key[ptr++])
{
// System.out.printf ("%04X: %02X != %02X%n", offset, buffer[offset], key[ptr]);
return false; return false;
}
// System.out.printf ("%04X: %02X == %02X%n", offset, buffer[offset - 1],
// key[ptr - 1]);
}
return true; return true;
} }
} }

View File

@ -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<AppleDisk> disks = new ArrayList<AppleDisk> ();
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;
}
}

View File

@ -9,7 +9,11 @@ import javax.swing.tree.DefaultTreeModel;
import com.bytezone.diskbrowser.applefile.AbstractFile; import com.bytezone.diskbrowser.applefile.AbstractFile;
import com.bytezone.diskbrowser.applefile.AppleFileSource; 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.gui.DataSource;
import com.bytezone.diskbrowser.pascal.PascalDisk; import com.bytezone.diskbrowser.pascal.PascalDisk;
import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.HexFormatter;
@ -93,7 +97,8 @@ public class WizardryScenarioDisk extends PascalDisk
extractMonsters (linkNode ("Monsters", "Monsters string", dataNode), sectors); extractMonsters (linkNode ("Monsters", "Monsters string", dataNode), sectors);
extractCharacters (linkNode ("Characters", "Characters string", dataNode), sectors); extractCharacters (linkNode ("Characters", "Characters string", dataNode), sectors);
extractImages (linkNode ("Images", "Images 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 = linkNode ("Spells", "Spells string", dataNode);
node = null; node = null;
extractSpells (node, sectors); extractSpells (node, sectors);
@ -112,7 +117,7 @@ public class WizardryScenarioDisk extends PascalDisk
} }
private DefaultMutableTreeNode linkNode (String name, String text, private DefaultMutableTreeNode linkNode (String name, String text,
DefaultMutableTreeNode parent) DefaultMutableTreeNode parent)
{ {
DefaultAppleFileSource afs = new DefaultAppleFileSource (name, text, this); DefaultAppleFileSource afs = new DefaultAppleFileSource (name, text, this);
DefaultMutableTreeNode node = new DefaultMutableTreeNode (afs); DefaultMutableTreeNode node = new DefaultMutableTreeNode (afs);
@ -131,7 +136,7 @@ public class WizardryScenarioDisk extends PascalDisk
{ {
String text = HexFormatter.getPascalString (buffer, ptr); String text = HexFormatter.getPascalString (buffer, ptr);
if (!text.equals ("SCENARIO.DATA") && !text.equals ("SCENARIO.MESGS") if (!text.equals ("SCENARIO.DATA") && !text.equals ("SCENARIO.MESGS")
&& !text.equals ("WIZARDRY.CODE")) && !text.equals ("WIZARDRY.CODE"))
return false; return false;
} }
return true; return true;
@ -187,8 +192,8 @@ public class WizardryScenarioDisk extends PascalDisk
dds.text = text.toString (); dds.text = text.toString ();
} }
private int addReward (byte[] buffer, List<DiskAddress> blocks, DefaultMutableTreeNode node, private int addReward (byte[] buffer, List<DiskAddress> blocks,
int seq) DefaultMutableTreeNode node, int seq)
{ {
int recLen = 168; int recLen = 168;
for (int ptr = 0; ptr < 1008; ptr += recLen) for (int ptr = 0; ptr < 1008; ptr += recLen)
@ -222,20 +227,20 @@ public class WizardryScenarioDisk extends PascalDisk
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
text.append ("Name Age Align Race Type " 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 ("------------- ---- -------- -------- ---------- " text.append ("------------- ---- -------- -------- ---------- "
+ "-- -- -- -- -- -- -- ------\n"); + "-- -- -- -- -- -- -- ------\n");
for (Character ch : characters) for (Character ch : characters)
{ {
Statistics stats = ch.getStatistics (); Statistics stats = ch.getStatistics ();
Attributes att = ch.getAttributes (); Attributes att = ch.getAttributes ();
text.append (String.format ("%-15s %2d %-8s %-8s %-8s %3d", ch, text.append (
(stats.ageInWeeks / 52), stats.alignment, stats.race, String.format ("%-15s %2d %-8s %-8s %-8s %3d", ch, (stats.ageInWeeks / 52),
stats.type, stats.hitsMax)); stats.alignment, stats.race, stats.type, stats.hitsMax));
text.append (String.format (" %2d %2d %2d %2d %2d %2d", att.strength, text.append (String.format (" %2d %2d %2d %2d %2d %2d", att.strength,
att.intelligence, att.piety, att.vitality, att.agility, att.intelligence, att.piety, att.vitality, att.agility, att.luck));
att.luck)); text.append (
text.append (String.format (" %5s %s%n", stats.status, ch.isOut () ? "* OUT *" : "")); String.format (" %5s %s%n", stats.status, ch.isOut () ? "* OUT *" : ""));
} }
DefaultAppleFileSource afs = (DefaultAppleFileSource) node.getUserObject (); DefaultAppleFileSource afs = (DefaultAppleFileSource) node.getUserObject ();
@ -245,7 +250,7 @@ public class WizardryScenarioDisk extends PascalDisk
} }
private void addCharacters (byte[] buffer, List<DiskAddress> blocks, private void addCharacters (byte[] buffer, List<DiskAddress> blocks,
DefaultMutableTreeNode node) DefaultMutableTreeNode node)
{ {
int recLen = 208; int recLen = 208;
for (int ptr = 0; ptr < 832; ptr += recLen) for (int ptr = 0; ptr < 832; ptr += recLen)
@ -298,7 +303,7 @@ public class WizardryScenarioDisk extends PascalDisk
} }
private void addMonsters (byte[] buffer, List<DiskAddress> blocks, private void addMonsters (byte[] buffer, List<DiskAddress> blocks,
DefaultMutableTreeNode node) DefaultMutableTreeNode node)
{ {
int recLen = 158; int recLen = 158;
for (int ptr = 0; ptr < 948; ptr += recLen) for (int ptr = 0; ptr < 948; ptr += recLen)
@ -350,7 +355,8 @@ public class WizardryScenarioDisk extends PascalDisk
dds.text = text.toString (); dds.text = text.toString ();
} }
private void addItems (byte[] buffer, List<DiskAddress> blocks, DefaultMutableTreeNode node) private void addItems (byte[] buffer, List<DiskAddress> blocks,
DefaultMutableTreeNode node)
{ {
int recLen = 78; int recLen = 78;
for (int ptr = 0; ptr < 1014; ptr += recLen) 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) AbstractImage mi = scenarioHeader.scenarioID < 3 ? new Image (name, buffer)
: new ImageV2 (name, exactBuffer); : new ImageV2 (name, exactBuffer);
images.add (mi); images.add (mi);
addToNode (mi, node, da, imageSector); addToNode (mi, node, da, imageSector);
} }
@ -538,7 +544,8 @@ public class WizardryScenarioDisk extends PascalDisk
dds.text = text.toString (); dds.text = text.toString ();
} }
private void extractExperienceLevels (DefaultMutableTreeNode node, List<DiskAddress> sectors) private void extractExperienceLevels (DefaultMutableTreeNode node,
List<DiskAddress> sectors)
{ {
List<DiskAddress> nodeSectors = new ArrayList<DiskAddress> (); List<DiskAddress> nodeSectors = new ArrayList<DiskAddress> ();
ScenarioData sd = scenarioHeader.data.get (Header.EXPERIENCE_AREA); 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, private void addToNode (AbstractFile af, DefaultMutableTreeNode node, DiskAddress block,
SectorType type) SectorType type)
{ {
ArrayList<DiskAddress> blocks = new ArrayList<DiskAddress> (1); ArrayList<DiskAddress> blocks = new ArrayList<DiskAddress> (1);
blocks.add (block); blocks.add (block);
@ -577,15 +584,17 @@ public class WizardryScenarioDisk extends PascalDisk
} }
private void addToNode (AbstractFile af, DefaultMutableTreeNode node, private void addToNode (AbstractFile af, DefaultMutableTreeNode node,
List<DiskAddress> blocks, SectorType type) List<DiskAddress> 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); DefaultMutableTreeNode childNode = new DefaultMutableTreeNode (dafs);
node.add (childNode); node.add (childNode);
childNode.setAllowsChildren (false); childNode.setAllowsChildren (false);
} }
private List<DiskAddress> getTwoBlocks (ScenarioData sd, int i, List<DiskAddress> sectors) private List<DiskAddress> getTwoBlocks (ScenarioData sd, int i,
List<DiskAddress> sectors)
{ {
ArrayList<DiskAddress> blocks = new ArrayList<DiskAddress> (2); ArrayList<DiskAddress> blocks = new ArrayList<DiskAddress> (2);
blocks.add (sectors.get (sd.dataOffset + i * 2)); blocks.add (sectors.get (sd.dataOffset + i * 2));