Relocator returns MultiDiskAddress

This commit is contained in:
Denis Molony 2016-08-05 18:40:32 +10:00
parent 85e1f945cd
commit f3b2d03e58
6 changed files with 146 additions and 44 deletions

View File

@ -4,14 +4,17 @@ 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;
public class PascalCode extends AbstractFile public class PascalCode extends AbstractFile
implements PascalConstants, Iterable<PascalSegment> implements PascalConstants, Iterable<PascalSegment>
{ {
List<PascalSegment> segments = new ArrayList<PascalSegment> (16); private final List<PascalSegment> segments = new ArrayList<PascalSegment> (16);
String comment; private final String comment;
private final int blockOffset;
private final Relocator relocator;
public static void print () public static void print ()
{ {
@ -20,9 +23,13 @@ public class PascalCode extends AbstractFile
PascalConstants.mnemonics[i], PascalConstants.descriptions[i]); PascalConstants.mnemonics[i], PascalConstants.descriptions[i]);
} }
public PascalCode (String name, byte[] buffer) public PascalCode (String name, byte[] buffer, int blockOffset, Relocator relocator)
{ {
super (name, buffer); super (name, buffer);
this.blockOffset = blockOffset;
this.relocator = relocator;
int nonameCounter = 0; int nonameCounter = 0;
if (false) if (false)
{ {
@ -54,13 +61,51 @@ public class PascalCode extends AbstractFile
text.append ("Segment Dictionary\n==================\n\n"); text.append ("Segment Dictionary\n==================\n\n");
text.append ("Slot Addr Blks Len Len Name Kind" text.append ("Slot Addr Addr Blks Len D:Blk Name Kind"
+ " Txt Seg Mch Ver I/S I/S\n"); + " Txt Seg Mch Ver I/S I/S\n");
text.append ("---- ---- ---- ---- ----- -------- ---------------" text.append ("---- ---- ---- ---- ---- ----- -------- ---------------"
+ " --- --- --- --- --- ---\n"); + " --- --- --- --- --- ---\n");
MultiDiskAddress lastMultiDiskAddress = null;
int minBlocks = 0;
int maxBlocks = 0;
for (PascalSegment segment : segments) for (PascalSegment segment : segments)
text.append (segment.toText () + "\n"); {
int sizeInBlocks = (segment.size - 1) / 512 + 1;
String multiDiskAddressText = "";
if (segment.segmentNoHeader == 1) // main segment
{
multiDiskAddressText = String.format ("1:%03X", (segment.blockNo + blockOffset));
}
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);
}
else
{
int targetBlock = segment.blockNo + blockOffset;
List<MultiDiskAddress> addresses = relocator.getMultiDiskAddress (targetBlock);
if (addresses.isEmpty ())
multiDiskAddressText = ".";
else
{
lastMultiDiskAddress = addresses.get (0);
multiDiskAddressText = addresses.get (0).toString ();
if (lastMultiDiskAddress.totalBlocks > sizeInBlocks)
{
minBlocks = segment.blockNo;
maxBlocks = minBlocks + lastMultiDiskAddress.totalBlocks;
}
}
}
}
text.append (segment.toText (blockOffset, multiDiskAddressText) + "\n");
}
text.append ("\nComment : " + comment + "\n\n"); text.append ("\nComment : " + comment + "\n\n");
return text.toString (); return text.toString ();

View File

@ -8,7 +8,7 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
public class PascalSegment extends AbstractFile implements PascalConstants public class PascalSegment extends AbstractFile implements PascalConstants
{ {
private final int segmentNoHeader; final int segmentNoHeader;
private int segmentNoBody; private int segmentNoBody;
public int blockNo; public int blockNo;
@ -112,16 +112,18 @@ public class PascalSegment extends AbstractFile implements PascalConstants
procedures.add (new PascalProcedure (buffer, i)); procedures.add (new PascalProcedure (buffer, i));
} }
public String toText () public String toText (int offset, String multiDiskAddress)
{ {
int sizeInBlocks = (size - 1) / 512 + 1; int sizeInBlocks = (size - 1) / 512 + 1;
String newBlock = newBlockNo > 0 ? String.format ("%02X + %02X = %02X", newBlockNo, String newBlock = newBlockNo > 0 ? String.format ("%02X + %02X = %02X", newBlockNo,
sizeInBlocks, (newBlockNo + sizeInBlocks)) : ""; sizeInBlocks, (newBlockNo + sizeInBlocks)) : "";
return String.format ( return String.format (
" %2d %02X %02X %04X %,6d %-8s %-15s%3d " " %2d %02X %02X %02X %04X %6s %-8s %-15s%3d "
+ "%02X %d %d %d %d %s", + "%02X %d %d %d %d %s",
slot, blockNo, sizeInBlocks, size, size, name, SegmentKind[segKind], textAddress, slot, blockNo, (blockNo + offset), sizeInBlocks, size, multiDiskAddress, name,
segmentNoHeader, machineType, version, intrinsSegs1, intrinsSegs2, newBlock); SegmentKind[segKind], textAddress, segmentNoHeader, machineType, version,
intrinsSegs1, intrinsSegs2, newBlock);
} }
@Override @Override

View File

@ -26,6 +26,20 @@ public class Relocator extends AbstractFile
} }
} }
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));
return addresses;
}
@Override @Override
public String getText () public String getText ()
{ {
@ -46,25 +60,25 @@ public class Relocator extends AbstractFile
private class DiskRecord private class DiskRecord
{ {
int diskNumber; int diskNumber;
int diskSegments; int totDiskSegments;
List<Segment> segments = new ArrayList<Segment> (); List<DiskSegment> diskSegments = new ArrayList<DiskSegment> ();
public DiskRecord (byte[] buffer, int ptr) public DiskRecord (byte[] buffer, int ptr)
{ {
diskNumber = HexFormatter.intValue (buffer[ptr], buffer[ptr + 1]); diskNumber = HexFormatter.intValue (buffer[ptr], buffer[ptr + 1]);
diskSegments = HexFormatter.intValue (buffer[ptr + 2], buffer[ptr + 4]); totDiskSegments = HexFormatter.intValue (buffer[ptr + 2], buffer[ptr + 4]);
ptr += 4; ptr += 4;
for (int i = 0; i < diskSegments; i++) for (int i = 0; i < totDiskSegments; i++)
{ {
segments.add (new Segment (buffer, ptr)); diskSegments.add (new DiskSegment (buffer, ptr));
ptr += 6; ptr += 6;
} }
} }
int size () int size ()
{ {
return 4 + segments.size () * 6; return 4 + diskSegments.size () * 6;
} }
@Override @Override
@ -72,25 +86,28 @@ public class Relocator extends AbstractFile
{ {
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
int offset = 0xe2;
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", diskSegments)); text.append (String.format ("Segments....... %04X%n%n", totDiskSegments));
text.append ("Segment Logical Physical Length\n"); text.append (String.format (
"Segment Logical Physical Length -%04X -%04X%n", offset, offset));
int count = 1; int count = 1;
for (Segment segment : segments) for (DiskSegment segment : diskSegments)
text.append (String.format (" %02X %s %n", count++, segment)); text.append (String.format (" %02X %s %n", count++, segment.toString (offset)));
return text.toString (); return text.toString ();
} }
} }
private class Segment private class DiskSegment
{ {
int logicalBlock; int logicalBlock;
int physicalBlock; int physicalBlock;
int segmentLength; int segmentLength;
public Segment (byte[] buffer, int ptr) public DiskSegment (byte[] buffer, int ptr)
{ {
logicalBlock = HexFormatter.intValue (buffer[ptr], buffer[ptr + 1]); logicalBlock = HexFormatter.intValue (buffer[ptr], buffer[ptr + 1]);
physicalBlock = HexFormatter.intValue (buffer[ptr + 2], buffer[ptr + 3]); physicalBlock = HexFormatter.intValue (buffer[ptr + 2], buffer[ptr + 3]);
@ -100,9 +117,39 @@ public class Relocator extends AbstractFile
@Override @Override
public String toString () public String toString ()
{ {
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", return String.format (" %04X %04X %04X %04X %04X",
logicalBlock, physicalBlock, segmentLength, logicalBlock, physicalBlock, segmentLength, logical, physical);
(logicalBlock - 0x46), (physicalBlock - 0x46)); return String.format (" %04X %04X %04X", logicalBlock, physicalBlock,
segmentLength);
}
}
class MultiDiskAddress
{
int diskNumber;
int blockNumber;
int totalBlocks;
public MultiDiskAddress (int diskNumber, int blockNumber, int totalBlocks)
{
this.diskNumber = diskNumber;
this.blockNumber = blockNumber;
this.totalBlocks = totalBlocks;
}
@Override
public String toString ()
{
return String.format ("%d:%03X", diskNumber, blockNumber);
} }
} }
} }

View File

@ -7,11 +7,13 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
class FileEntry extends CatalogEntry class FileEntry extends CatalogEntry
{ {
int bytesUsedInLastBlock; int bytesUsedInLastBlock;
private final Relocator relocator;
public FileEntry (PascalDisk parent, byte[] buffer) public FileEntry (PascalDisk parent, byte[] buffer, Relocator relocator)
{ {
super (parent, buffer); super (parent, buffer);
this.relocator = relocator;
bytesUsedInLastBlock = HexFormatter.intValue (buffer[22], buffer[23]); bytesUsedInLastBlock = HexFormatter.intValue (buffer[22], buffer[23]);
date = HexFormatter.getPascalDate (buffer, 24); date = HexFormatter.getPascalDate (buffer, 24);
@ -67,7 +69,7 @@ class FileEntry extends CatalogEntry
case 2: // code (6502 or Pascal) case 2: // code (6502 or Pascal)
try try
{ {
file = new PascalCode (name, buffer); file = new PascalCode (name, buffer, firstBlock, relocator);
} }
catch (FileFormatException e) catch (FileFormatException e)
{ {

View File

@ -12,6 +12,7 @@ import com.bytezone.diskbrowser.applefile.AppleFileSource;
import com.bytezone.diskbrowser.applefile.BootSector; import com.bytezone.diskbrowser.applefile.BootSector;
import com.bytezone.diskbrowser.applefile.PascalCode; import com.bytezone.diskbrowser.applefile.PascalCode;
import com.bytezone.diskbrowser.applefile.PascalSegment; import com.bytezone.diskbrowser.applefile.PascalSegment;
import com.bytezone.diskbrowser.applefile.Relocator;
import com.bytezone.diskbrowser.disk.*; import com.bytezone.diskbrowser.disk.*;
import com.bytezone.diskbrowser.gui.DataSource; import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.HexFormatter;
@ -22,6 +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;
final String[] fileTypes = final String[] fileTypes =
{ "Volume", "Xdsk", "Code", "Text", "Info", "Data", "Graf", "Foto", "SecureDir" }; { "Volume", "Xdsk", "Code", "Text", "Info", "Data", "Graf", "Foto", "SecureDir" };
@ -99,11 +101,14 @@ public class PascalDisk extends AbstractFormattedDisk
data = new byte[CATALOG_ENTRY_SIZE]; data = new byte[CATALOG_ENTRY_SIZE];
System.arraycopy (buffer, ptr, data, 0, CATALOG_ENTRY_SIZE); System.arraycopy (buffer, ptr, data, 0, CATALOG_ENTRY_SIZE);
FileEntry fileEntry = new FileEntry (this, data); FileEntry fileEntry = new FileEntry (this, data, relocator);
fileEntries.add (fileEntry); fileEntries.add (fileEntry);
DefaultMutableTreeNode node = new DefaultMutableTreeNode (fileEntry); DefaultMutableTreeNode node = new DefaultMutableTreeNode (fileEntry);
if (fileEntry.fileType == 2 && fileEntry.getDataSource () instanceof PascalCode) // PascalCode if (fileEntry.fileType == 5 && fileEntry.getDataSource () instanceof Relocator)
this.relocator = (Relocator) fileEntry.getDataSource ();
if (fileEntry.fileType == 2 && fileEntry.getDataSource () instanceof PascalCode)
{ {
node.setAllowsChildren (true); node.setAllowsChildren (true);
PascalCode pascalCode = (PascalCode) fileEntry.getDataSource (); PascalCode pascalCode = (PascalCode) fileEntry.getDataSource ();
@ -258,16 +263,16 @@ public class PascalDisk extends AbstractFormattedDisk
{ {
String newLine = String.format ("%n"); String newLine = String.format ("%n");
String newLine2 = newLine + newLine; String newLine2 = newLine + newLine;
String line = String line = "---- --------------- ---- -------- ------- ---- ---- ----"
"---- --------------- ---- -------- ------- ---- ----" + newLine; + newLine;
String date = String date =
volumeEntry.date == null ? "--" : df.format (volumeEntry.date.getTime ()); volumeEntry.date == null ? "--" : df.format (volumeEntry.date.getTime ());
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
text.append ("Disk : " + disk.getFile ().getAbsolutePath () + newLine2); text.append ("Disk : " + disk.getFile ().getAbsolutePath () + newLine2);
text.append ("Volume : " + volumeEntry.name + newLine); text.append ("Volume : " + volumeEntry.name + newLine);
text.append ("Date : " + date + newLine2); text.append ("Date : " + date + newLine2);
text.append ("Blks Name Type Date Length Frst Last" text.append (
+ newLine); "Blks Name Type Date Length Frst Last Blks\n");
text.append (line); text.append (line);
int usedBlocks = 6; int usedBlocks = 6;
@ -278,15 +283,14 @@ public class PascalDisk extends AbstractFormattedDisk
usedBlocks += size; usedBlocks += size;
date = ce.date == null ? "--" : df.format (ce.date.getTime ()); date = ce.date == null ? "--" : df.format (ce.date.getTime ());
int bytes = (size - 1) * 512 + ce.bytesUsedInLastBlock; int bytes = (size - 1) * 512 + ce.bytesUsedInLastBlock;
text.append (String.format ("%4d %-15s %s %8s %,8d $%03X $%03X%n", size, text.append (String.format ("%4d %-15s %s %8s %,8d $%03X $%03X $%03X%n",
ce.name, fileTypes[ce.fileType], date, bytes, size, ce.name, fileTypes[ce.fileType], date, bytes, ce.firstBlock, ce.lastBlock,
ce.firstBlock, ce.lastBlock)); size));
} }
text.append (line); text.append (line);
text.append (String.format ( text.append (
"Blocks free : %3d Blocks used : %3d Total blocks : %3d%n", String.format ("Blocks free : %3d Blocks used : %3d Total blocks : %3d%n",
(volumeEntry.totalBlocks - usedBlocks), usedBlocks, (volumeEntry.totalBlocks - usedBlocks), usedBlocks, volumeEntry.totalBlocks));
volumeEntry.totalBlocks));
return new DefaultAppleFileSource (volumeEntry.name, text.toString (), this); return new DefaultAppleFileSource (volumeEntry.name, text.toString (), this);
} }
} }

View File

@ -55,6 +55,8 @@ public class HexFormatter
{ {
if (line.length () > 0 && i > 0) if (line.length () > 0 && i > 0)
line.append ("\n"); line.append ("\n");
if (i > 0 && (i % 0x200) == 0)
line.append ("\n");
// print offset // print offset
for (int temp = i + startingAddress, max = 65536; max > 0; max /= 16) for (int temp = i + startingAddress, max = 65536; max > 0; max /= 16)
@ -106,8 +108,8 @@ public class HexFormatter
if (freq[i] > 0) if (freq[i] > 0)
{ {
totalBits += (Integer.bitCount (i) * freq[i]); totalBits += (Integer.bitCount (i) * freq[i]);
line.append (String.format ("%02X %3d %d%n", i, freq[i], line.append (
Integer.bitCount (i))); String.format ("%02X %3d %d%n", i, freq[i], Integer.bitCount (i)));
} }
line.append (String.format ("%nTotal bits : %d%n", totalBits)); line.append (String.format ("%nTotal bits : %d%n", totalBits));
} }