multi-disk segments

This commit is contained in:
Denis Molony 2016-08-06 07:29:27 +10:00
parent f3b2d03e58
commit c5aabdf3b2
3 changed files with 105 additions and 48 deletions

View File

@ -61,18 +61,15 @@ public class PascalCode extends AbstractFile
text.append ("Segment Dictionary\n==================\n\n");
text.append ("Slot Addr Addr Blks Len D:Blk Name Kind"
+ " Txt Seg Mch Ver I/S I/S\n");
text.append ("---- ---- ---- ---- ---- ----- -------- ---------------"
+ " --- --- --- --- --- ---\n");
MultiDiskAddress lastMultiDiskAddress = null;
int minBlocks = 0;
int maxBlocks = 0;
text.append ("Slot Addr Blks Len Name Kind"
+ " Txt Seg Mch Ver I/S I/S D:Blk\n");
text.append ("---- ---- ---- ---- -------- ---------------"
+ " --- --- --- --- --- --- ---------------------\n");
for (PascalSegment segment : segments)
{
int sizeInBlocks = (segment.size - 1) / 512 + 1;
System.out.printf ("Seg: %-8s add: %03X%n", segment.name, segment.blockNo);
String multiDiskAddressText = "";
if (segment.segmentNoHeader == 1) // main segment
{
@ -80,33 +77,28 @@ public class PascalCode extends AbstractFile
}
else if (relocator != null)
{
if (segment.blockNo >= minBlocks && segment.blockNo < maxBlocks)
{
int offset = segment.blockNo - minBlocks;
multiDiskAddressText = String.format ("%d:%03X",
lastMultiDiskAddress.diskNumber, lastMultiDiskAddress.blockNumber + offset);
}
int targetBlock = segment.blockNo + blockOffset;
List<MultiDiskAddress> addresses =
relocator.getMultiDiskAddress (segment.name, targetBlock, sizeInBlocks);
if (addresses.isEmpty ())
multiDiskAddressText = ".";
else
{
int targetBlock = segment.blockNo + blockOffset;
List<MultiDiskAddress> addresses = relocator.getMultiDiskAddress (targetBlock);
if (addresses.isEmpty ())
multiDiskAddressText = ".";
else
StringBuilder locations = new StringBuilder ();
for (MultiDiskAddress multiDiskAddress : addresses)
locations.append (multiDiskAddress.toString () + ", ");
if (locations.length () > 2)
{
lastMultiDiskAddress = addresses.get (0);
multiDiskAddressText = addresses.get (0).toString ();
if (lastMultiDiskAddress.totalBlocks > sizeInBlocks)
{
minBlocks = segment.blockNo;
maxBlocks = minBlocks + lastMultiDiskAddress.totalBlocks;
}
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 ();
}

View File

@ -115,15 +115,12 @@ public class PascalSegment extends AbstractFile implements PascalConstants
public String toText (int offset, String multiDiskAddress)
{
int sizeInBlocks = (size - 1) / 512 + 1;
String newBlock = newBlockNo > 0 ? String.format ("%02X + %02X = %02X", newBlockNo,
sizeInBlocks, (newBlockNo + sizeInBlocks)) : "";
return String.format (
" %2d %02X %02X %02X %04X %6s %-8s %-15s%3d "
+ "%02X %d %d %d %d %s",
slot, blockNo, (blockNo + offset), sizeInBlocks, size, multiDiskAddress, name,
SegmentKind[segKind], textAddress, segmentNoHeader, machineType, version,
intrinsSegs1, intrinsSegs2, newBlock);
" %2d %02X %02X %04X %-8s %-15s%3d " + "%02X %d %d %d %d %s",
slot, blockNo, sizeInBlocks, size, name, SegmentKind[segKind], textAddress,
segmentNoHeader, machineType, version, intrinsSegs1, intrinsSegs2,
multiDiskAddress);
}
@Override

View File

@ -1,6 +1,7 @@
package com.bytezone.diskbrowser.applefile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.bytezone.diskbrowser.utilities.HexFormatter;
@ -9,6 +10,7 @@ public class Relocator extends AbstractFile
{
private final int checkByte;
private final List<DiskRecord> diskRecords = new ArrayList<DiskRecord> ();
private final List<MultiDiskAddress> addresses = new ArrayList<MultiDiskAddress> ();
public Relocator (String name, byte[] buffer)
{
@ -24,20 +26,67 @@ public class Relocator extends AbstractFile
diskRecords.add (diskRecord);
ptr += diskRecord.size ();
}
}
public List<MultiDiskAddress> getMultiDiskAddress (int blockNumber)
{
System.out.printf ("searching for %04X%n", blockNumber);
List<MultiDiskAddress> addresses = new ArrayList<MultiDiskAddress> ();
for (DiskRecord diskRecord : diskRecords)
for (DiskSegment diskSegment : diskRecord.diskSegments)
if (diskSegment.logicalBlock == blockNumber)
addresses.add (new MultiDiskAddress (diskRecord.diskNumber,
diskSegment.physicalBlock, diskSegment.segmentLength));
addresses
.add (new MultiDiskAddress (diskRecord.diskNumber, diskSegment.logicalBlock,
diskSegment.physicalBlock, diskSegment.segmentLength));
return addresses;
list ();
}
public void list ()
{
for (MultiDiskAddress multiDiskAddress : addresses)
System.out.printf ("%d %03X %03X %03X %s%n", multiDiskAddress.diskNumber,
multiDiskAddress.logicalBlockNumber, multiDiskAddress.physicalBlockNumber,
multiDiskAddress.totalBlocks, multiDiskAddress.name);
}
public List<MultiDiskAddress> getMultiDiskAddress (String name, int blockNumber,
int length)
{
List<MultiDiskAddress> foundAddresses = new ArrayList<MultiDiskAddress> ();
List<MultiDiskAddress> newAddresses = new ArrayList<MultiDiskAddress> ();
List<MultiDiskAddress> oldAddresses = new ArrayList<MultiDiskAddress> ();
for (MultiDiskAddress multiDiskAddress : addresses)
{
if (multiDiskAddress.logicalBlockNumber == blockNumber)
{
if (multiDiskAddress.totalBlocks == length)
{
foundAddresses.add (multiDiskAddress);
if (multiDiskAddress.name.isEmpty ())
multiDiskAddress.name = name;
}
else if (multiDiskAddress.totalBlocks > length)
{
MultiDiskAddress newAddress1 = new MultiDiskAddress (
multiDiskAddress.diskNumber, multiDiskAddress.logicalBlockNumber,
multiDiskAddress.physicalBlockNumber, length, name);
MultiDiskAddress newAddress2 = new MultiDiskAddress (
multiDiskAddress.diskNumber, multiDiskAddress.logicalBlockNumber + length,
multiDiskAddress.physicalBlockNumber + length,
multiDiskAddress.totalBlocks - length);
oldAddresses.add (multiDiskAddress);
newAddresses.add (newAddress1);
newAddresses.add (newAddress2);
foundAddresses.add (newAddress1);
}
}
}
if (newAddresses.size () > 0)
{
addresses.addAll (newAddresses);
addresses.removeAll (oldAddresses);
Collections.sort (addresses);
}
return foundAddresses;
}
@Override
@ -133,23 +182,42 @@ public class Relocator extends AbstractFile
}
}
class MultiDiskAddress
class MultiDiskAddress implements Comparable<MultiDiskAddress>
{
int diskNumber;
int blockNumber;
int logicalBlockNumber;
int physicalBlockNumber;
int totalBlocks;
String name = "";
public MultiDiskAddress (int diskNumber, int blockNumber, int totalBlocks)
public MultiDiskAddress (int diskNumber, int logicalBlockNumber,
int physicalBlockNumber, int totalBlocks)
{
this.diskNumber = diskNumber;
this.blockNumber = blockNumber;
this.logicalBlockNumber = logicalBlockNumber;
this.physicalBlockNumber = physicalBlockNumber;
this.totalBlocks = totalBlocks;
}
public MultiDiskAddress (int diskNumber, int logicalBlockNumber,
int physicalBlockNumber, int totalBlocks, String name)
{
this (diskNumber, logicalBlockNumber, physicalBlockNumber, totalBlocks);
this.name = name;
}
@Override
public String toString ()
{
return String.format ("%d:%03X", diskNumber, blockNumber);
return String.format ("%d:%03X", diskNumber, physicalBlockNumber);
}
@Override
public int compareTo (MultiDiskAddress o)
{
if (this.diskNumber == o.diskNumber)
return this.logicalBlockNumber - o.logicalBlockNumber;
return this.diskNumber - o.diskNumber;
}
}
}