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.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<MultiDiskAddress> newAddresses = 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)
{
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<MultiDiskAddress> 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<MultiDiskAddress>

View File

@ -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)

View File

@ -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)
{

View File

@ -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)

View File

@ -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)
{

View File

@ -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;

View File

@ -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));
}

View File

@ -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<DiskAddress> blocks = disk.getDiskAddressList (0, 1);
this.bootSector = new BootSector (disk, disk.readSectors (blocks), "Pascal");//, blocks);
List<DiskAddress> 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<DiskAddress> sectors = new ArrayList<DiskAddress> ();
@ -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)
{

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;
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;
}
}

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.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<DiskAddress> blocks, DefaultMutableTreeNode node,
int seq)
private int addReward (byte[] buffer, List<DiskAddress> 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<DiskAddress> 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<DiskAddress> 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<DiskAddress> blocks, DefaultMutableTreeNode node)
private void addItems (byte[] buffer, List<DiskAddress> 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<DiskAddress> sectors)
private void extractExperienceLevels (DefaultMutableTreeNode node,
List<DiskAddress> sectors)
{
List<DiskAddress> nodeSectors = new ArrayList<DiskAddress> ();
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<DiskAddress> blocks = new ArrayList<DiskAddress> (1);
blocks.add (block);
@ -577,15 +584,17 @@ public class WizardryScenarioDisk extends PascalDisk
}
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);
node.add (childNode);
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);
blocks.add (sectors.get (sd.dataOffset + i * 2));