moved multi disk code to PascalSegment

This commit is contained in:
Denis Molony 2016-08-06 10:02:45 +10:00
parent c5aabdf3b2
commit f47ae78cfb
3 changed files with 87 additions and 91 deletions

View File

@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import com.bytezone.diskbrowser.applefile.Relocator.MultiDiskAddress;
import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility; import com.bytezone.diskbrowser.utilities.Utility;
@ -46,11 +45,14 @@ public class PascalCode extends AbstractFile
int size = HexFormatter.intValue (buffer[i * 4 + 2], buffer[i * 4 + 3]); int size = HexFormatter.intValue (buffer[i * 4 + 2], buffer[i * 4 + 3]);
if (codeName.length () == 0 && size > 0) if (codeName.length () == 0 && size > 0)
codeName = "<NULL" + ++nonameCounter + ">"; codeName = "<NULL" + ++nonameCounter + ">";
// System.out.printf ("%s %s %d %n", HexFormatter.getHexString (buffer, i * 4, 4),
// codeName, size);
if (size > 0) if (size > 0)
segments.add (new PascalSegment (codeName, buffer, i)); {
PascalSegment pascalSegment =
new PascalSegment (codeName, buffer, i, blockOffset, relocator);
segments.add (pascalSegment);
}
} }
comment = HexFormatter.getPascalString (buffer, 0x1B0); comment = HexFormatter.getPascalString (buffer, 0x1B0);
} }
@ -67,38 +69,9 @@ public class PascalCode extends AbstractFile
+ " --- --- --- --- --- --- ---------------------\n"); + " --- --- --- --- --- --- ---------------------\n");
for (PascalSegment segment : segments) for (PascalSegment segment : segments)
{ text.append (segment.toText () + "\n");
int sizeInBlocks = (segment.size - 1) / 512 + 1;
System.out.printf ("Seg: %-8s add: %03X%n", segment.name, segment.blockNo); text.append ("\nComment : " + comment);
String multiDiskAddressText = "";
if (segment.segmentNoHeader == 1) // main segment
{
multiDiskAddressText = String.format ("1:%03X", (segment.blockNo + blockOffset));
}
else if (relocator != null)
{
int targetBlock = segment.blockNo + blockOffset;
List<MultiDiskAddress> addresses =
relocator.getMultiDiskAddress (segment.name, targetBlock, sizeInBlocks);
if (addresses.isEmpty ())
multiDiskAddressText = ".";
else
{
StringBuilder locations = new StringBuilder ();
for (MultiDiskAddress multiDiskAddress : addresses)
locations.append (multiDiskAddress.toString () + ", ");
if (locations.length () > 2)
{
locations.deleteCharAt (locations.length () - 1);
locations.deleteCharAt (locations.length () - 1);
}
multiDiskAddressText = locations.toString ();
}
}
text.append (segment.toText (blockOffset, multiDiskAddressText) + "\n");
}
text.append ("\nComment : " + comment + "\n\n");
relocator.list ();
return text.toString (); return text.toString ();
} }

View File

@ -3,16 +3,20 @@ package com.bytezone.diskbrowser.applefile;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.bytezone.diskbrowser.applefile.Relocator.MultiDiskAddress;
import com.bytezone.diskbrowser.utilities.FileFormatException; import com.bytezone.diskbrowser.utilities.FileFormatException;
import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.HexFormatter;
public class PascalSegment extends AbstractFile implements PascalConstants public class PascalSegment extends AbstractFile implements PascalConstants
{ {
private final static int BLOCK_SIZE = 512;
final int segmentNoHeader; final int segmentNoHeader;
private int segmentNoBody; private int segmentNoBody;
private final int blockOffset;
private final Relocator relocator;
public int blockNo; public int blockNo;
public int newBlockNo; // public int newBlockNo;
public final int size; public final int size;
private final int segKind; private final int segKind;
@ -24,35 +28,20 @@ public class PascalSegment extends AbstractFile implements PascalConstants
private final int slot; private final int slot;
private int totalProcedures; private int totalProcedures;
private List<PascalProcedure> procedures; private List<PascalProcedure> procedures;
private static final List<Redirection> redirections = new ArrayList<Redirection> (); private List<MultiDiskAddress> addresses;
static public PascalSegment (String name, byte[] fullBuffer, int seq, int blockOffset,
{ Relocator relocator)
// somehow the offsets should match the data in SYSTEM.RELOC
redirections.add (new Redirection ("WIZARDRY", 0x01, 0x1C66, 0x01));
redirections.add (new Redirection ("KANJIREA", 0x3F, 0x104E, 0x10));
redirections.add (new Redirection ("UTILITIE", 0x48, 0x1598, 0x19));
redirections.add (new Redirection ("SHOPS ", 0x53, 0x0BE2, 0x24));
redirections.add (new Redirection ("CAMP ", 0x70, 0x24CA, 0x2A));
redirections.add (new Redirection ("DOCOPY ", 0x83, 0x07A0, 0x3D));
redirections.add (new Redirection ("DOCACHE ", 0x87, 0x072E, 0x41));
}
public PascalSegment (String name, byte[] fullBuffer, int seq)
{ {
super (name, fullBuffer); // sets this.buffer to the full buffer temporarily super (name, fullBuffer); // sets this.buffer to the full buffer temporarily
this.slot = seq; this.slot = seq;
this.blockOffset = blockOffset;
this.relocator = relocator;
this.blockNo = HexFormatter.intValue (fullBuffer[seq * 4], fullBuffer[seq * 4 + 1]); this.blockNo = HexFormatter.intValue (fullBuffer[seq * 4], fullBuffer[seq * 4 + 1]);
this.size = HexFormatter.intValue (fullBuffer[seq * 4 + 2], fullBuffer[seq * 4 + 3]); this.size = HexFormatter.intValue (fullBuffer[seq * 4 + 2], fullBuffer[seq * 4 + 3]);
for (Redirection redirection : redirections)
if (redirection.matches (name, blockNo, size))
{
newBlockNo = redirection.newOffset;
break;
}
segKind = HexFormatter.intValue (fullBuffer[0xC0 + seq * 2], segKind = HexFormatter.intValue (fullBuffer[0xC0 + seq * 2],
fullBuffer[0xC0 + seq * 2 + 1]); fullBuffer[0xC0 + seq * 2 + 1]);
@ -78,12 +67,30 @@ public class PascalSegment extends AbstractFile implements PascalConstants
fullBuffer[0x120 + seq * 4 + 3]); fullBuffer[0x120 + seq * 4 + 3]);
int offset = blockNo * 512; int offset = blockNo * 512;
if (newBlockNo > 0)
offset = newBlockNo * 512; if (relocator != null)
// System.out.printf ("Seq:%d, block:%d, size:%d, seg:%d, kind:%d, address:%d %n", seq, {
// blockNo, size, segmentNoHeader, segKind, textAddress); if (segmentNoHeader > 1)
// System.out.println (HexFormatter.format (fullBuffer)); {
if (offset < fullBuffer.length) int sizeInBlocks = (size - 1) / BLOCK_SIZE + 1;
int targetBlock = blockNo + blockOffset;
addresses = relocator.getMultiDiskAddress (name, targetBlock, sizeInBlocks);
if (addresses.size () > 0)
{
MultiDiskAddress multiDiskAddress = addresses.get (0);
if (multiDiskAddress.diskNumber == 1)
offset = (multiDiskAddress.physicalBlockNumber - blockOffset) * BLOCK_SIZE;
else
offset = -1;
}
}
}
if (offset < 0)
{
buffer = new byte[0];
}
else if (offset < fullBuffer.length)
{ {
buffer = new byte[size]; // replaces this.buffer with the segment buffer only buffer = new byte[size]; // replaces this.buffer with the segment buffer only
System.arraycopy (fullBuffer, offset, buffer, 0, size); System.arraycopy (fullBuffer, offset, buffer, 0, size);
@ -98,12 +105,15 @@ public class PascalSegment extends AbstractFile implements PascalConstants
} }
else else
{ {
// System.out.printf ("Error in blocksize %,d > %,d for pascal disk%n", offset,
// fullBuffer.length);
throw new FileFormatException ("Error in PascalSegment"); throw new FileFormatException ("Error in PascalSegment");
} }
} }
void setMultiDiskAddresses (List<MultiDiskAddress> addresses)
{
this.addresses = addresses;
}
private void buildProcedureList () private void buildProcedureList ()
{ {
procedures = new ArrayList<PascalProcedure> (totalProcedures); procedures = new ArrayList<PascalProcedure> (totalProcedures);
@ -112,15 +122,15 @@ public class PascalSegment extends AbstractFile implements PascalConstants
procedures.add (new PascalProcedure (buffer, i)); procedures.add (new PascalProcedure (buffer, i));
} }
public String toText (int offset, String multiDiskAddress) public String toText ()
{ {
int sizeInBlocks = (size - 1) / 512 + 1; int sizeInBlocks = (size - 1) / BLOCK_SIZE + 1;
return String.format ( return String.format (
" %2d %02X %02X %04X %-8s %-15s%3d " + "%02X %d %d %d %d %s", " %2d %02X %02X %04X %-8s %-15s%3d " + "%02X %d %d %d %d %s",
slot, blockNo, sizeInBlocks, size, name, SegmentKind[segKind], textAddress, slot, blockNo, sizeInBlocks, size, name, SegmentKind[segKind], textAddress,
segmentNoHeader, machineType, version, intrinsSegs1, intrinsSegs2, segmentNoHeader, machineType, version, intrinsSegs1, intrinsSegs2,
multiDiskAddress); getMultiDiskAddresses ());
} }
@Override @Override
@ -136,6 +146,8 @@ public class PascalSegment extends AbstractFile implements PascalConstants
String warning = segmentNoBody == segmentNoHeader ? "" String warning = segmentNoBody == segmentNoHeader ? ""
: String.format (" (%02X in header)", segmentNoHeader); : String.format (" (%02X in header)", segmentNoHeader);
text.append (String.format ("Address........ %02X%n", blockNo)); text.append (String.format ("Address........ %02X%n", blockNo));
if (addresses != null)
text.append (String.format ("Multi disk .... %s%n", getMultiDiskAddresses ()));
text.append (String.format ("Length......... %04X%n", buffer.length)); text.append (String.format ("Length......... %04X%n", buffer.length));
text.append (String.format ("Machine type... %d%n", machineType)); text.append (String.format ("Machine type... %d%n", machineType));
text.append (String.format ("Version........ %d%n", version)); text.append (String.format ("Version........ %d%n", version));
@ -181,25 +193,36 @@ public class PascalSegment extends AbstractFile implements PascalConstants
return text.toString (); return text.toString ();
} }
}
class Redirection private String getMultiDiskAddresses ()
{
int oldOffset;
int newOffset;
int length;
String name;
public Redirection (String name, int oldOffset, int length, int newOffset)
{ {
this.name = name.trim (); String multiDiskAddressText = "";
this.oldOffset = oldOffset; int sizeInBlocks = (size - 1) / BLOCK_SIZE + 1;
this.newOffset = newOffset;
this.length = length;
}
public boolean matches (String name, int offset, int length) if (segmentNoHeader == 1) // main segment
{ {
return this.name.equals (name) && this.oldOffset == offset && this.length == length; multiDiskAddressText = String.format ("1:%03X", (blockNo + blockOffset));
}
else if (relocator != null)
{
int targetBlock = blockNo + blockOffset;
List<MultiDiskAddress> addresses =
relocator.getMultiDiskAddress (name, targetBlock, sizeInBlocks);
if (addresses.isEmpty ())
multiDiskAddressText = ".";
else
{
StringBuilder locations = new StringBuilder ();
for (MultiDiskAddress multiDiskAddress : addresses)
locations.append (multiDiskAddress.toString () + ", ");
if (locations.length () > 2)
{
locations.deleteCharAt (locations.length () - 1);
locations.deleteCharAt (locations.length () - 1);
}
multiDiskAddressText = locations.toString ();
}
}
return multiDiskAddressText;
} }
} }

View File

@ -12,6 +12,9 @@ public class Relocator extends AbstractFile
private final List<DiskRecord> diskRecords = new ArrayList<DiskRecord> (); private final List<DiskRecord> diskRecords = new ArrayList<DiskRecord> ();
private final List<MultiDiskAddress> addresses = new ArrayList<MultiDiskAddress> (); private final List<MultiDiskAddress> addresses = new ArrayList<MultiDiskAddress> ();
private final List<MultiDiskAddress> newAddresses = new ArrayList<MultiDiskAddress> ();
private final List<MultiDiskAddress> oldAddresses = new ArrayList<MultiDiskAddress> ();
public Relocator (String name, byte[] buffer) public Relocator (String name, byte[] buffer)
{ {
super (name, buffer); super (name, buffer);
@ -32,13 +35,10 @@ public class Relocator extends AbstractFile
addresses addresses
.add (new MultiDiskAddress (diskRecord.diskNumber, diskSegment.logicalBlock, .add (new MultiDiskAddress (diskRecord.diskNumber, diskSegment.logicalBlock,
diskSegment.physicalBlock, diskSegment.segmentLength)); diskSegment.physicalBlock, diskSegment.segmentLength));
list ();
} }
public void list () public void list ()
{ {
for (MultiDiskAddress multiDiskAddress : addresses) for (MultiDiskAddress multiDiskAddress : addresses)
System.out.printf ("%d %03X %03X %03X %s%n", multiDiskAddress.diskNumber, System.out.printf ("%d %03X %03X %03X %s%n", multiDiskAddress.diskNumber,
multiDiskAddress.logicalBlockNumber, multiDiskAddress.physicalBlockNumber, multiDiskAddress.logicalBlockNumber, multiDiskAddress.physicalBlockNumber,
@ -49,8 +49,8 @@ public class Relocator extends AbstractFile
int length) int length)
{ {
List<MultiDiskAddress> foundAddresses = new ArrayList<MultiDiskAddress> (); List<MultiDiskAddress> foundAddresses = new ArrayList<MultiDiskAddress> ();
List<MultiDiskAddress> newAddresses = new ArrayList<MultiDiskAddress> (); newAddresses.clear ();
List<MultiDiskAddress> oldAddresses = new ArrayList<MultiDiskAddress> (); oldAddresses.clear ();
for (MultiDiskAddress multiDiskAddress : addresses) for (MultiDiskAddress multiDiskAddress : addresses)
{ {