dmolony-DiskBrowser/src/com/bytezone/diskbrowser/wizardry/Relocator.java

236 lines
7.4 KiB
Java
Raw Permalink Normal View History

2016-08-14 08:41:19 +00:00
package com.bytezone.diskbrowser.wizardry;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.applefile.AbstractFile;
import com.bytezone.diskbrowser.disk.AppleDisk;
import com.bytezone.diskbrowser.disk.Disk;
import com.bytezone.diskbrowser.disk.DiskAddress;
import com.bytezone.diskbrowser.utilities.Utility;
2016-08-14 08:41:19 +00:00
2020-02-11 07:29:55 +00:00
// -----------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
public class Relocator extends AbstractFile
2020-02-11 07:29:55 +00:00
// -----------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
{
private final int checkByte;
2020-02-02 10:17:49 +00:00
private final List<DiskRecord> diskRecords = new ArrayList<> ();
2016-08-14 08:41:19 +00:00
private final int[] diskBlocks = new int[0x800];
private final int[] diskOffsets = new int[0x800];
2020-02-11 07:29:55 +00:00
// ---------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
public Relocator (String name, byte[] buffer)
2020-02-11 07:29:55 +00:00
// ---------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
{
super (name, buffer);
2022-05-03 05:36:37 +00:00
checkByte = Utility.getShort (buffer, 0); // no of blocks?
2016-08-14 08:41:19 +00:00
int ptr = 2; // skip checkByte
while (buffer[ptr] != 0)
{
DiskRecord diskRecord = new DiskRecord (buffer, ptr);
diskRecords.add (diskRecord);
ptr += diskRecord.size ();
}
for (DiskRecord diskRecord : diskRecords)
for (DiskSegment diskSegment : diskRecord.diskSegments)
2022-05-03 05:36:37 +00:00
{
int lo = diskSegment.logicalBlock;
2022-05-27 08:30:30 +00:00
int hi = lo + diskSegment.segmentLength;
2016-08-14 08:41:19 +00:00
2022-05-03 05:36:37 +00:00
for (int i = lo, count = 0; i < hi; i++, count++)
2022-05-27 08:30:30 +00:00
if (diskBlocks[i] == 0) // doesn't matter either way
2022-05-03 05:36:37 +00:00
{
2022-05-27 08:30:30 +00:00
if (diskBlocks[i] != 0 && false)
{
System.out.print ("was: ");
System.out.printf ("diskBlocks[%d] = %d%n", i, diskBlocks[i]);
System.out.print ("now: ");
System.out.printf ("diskBlocks[%d] = %d%n", i, diskRecord.diskNumber);
}
diskBlocks[i] = diskRecord.diskNumber;
diskOffsets[i] = diskSegment.physicalBlock + count;
2022-05-03 05:36:37 +00:00
}
}
2016-08-14 08:41:19 +00:00
}
2020-02-11 07:29:55 +00:00
// ---------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
public void createNewBuffer (Disk[] dataDisks)
2020-02-11 07:29:55 +00:00
// ---------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
{
AppleDisk master = (AppleDisk) dataDisks[0];
for (int logicalBlock = 0; logicalBlock < diskBlocks.length; logicalBlock++)
{
int diskNo = diskBlocks[logicalBlock];
if (diskNo > 0)
{
Disk disk = dataDisks[diskNo];
2020-04-10 23:47:52 +00:00
byte[] temp = disk.readBlock (diskOffsets[logicalBlock]);
2016-08-14 08:41:19 +00:00
DiskAddress da = master.getDiskAddress (logicalBlock);
2020-04-10 23:47:52 +00:00
master.writeBlock (da, temp);
2016-08-14 08:41:19 +00:00
}
}
}
2020-02-11 07:29:55 +00:00
// ---------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
@Override
public String getText ()
2020-02-11 07:29:55 +00:00
// ---------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
{
StringBuilder text = new StringBuilder ();
text.append ("Pascal Relocator\n\n");
text.append (String.format ("Check byte..... %04X%n%n", checkByte));
for (DiskRecord diskRecord : diskRecords)
{
text.append (diskRecord);
text.append ("\n");
}
2020-02-02 10:17:49 +00:00
List<String> lines = new ArrayList<> ();
2016-08-14 08:41:19 +00:00
String heading = " Logical Size Disk Physical";
String underline = "--------- ---- ---- ---------";
int first = 0;
int lastDisk = diskBlocks[0];
int lastOffset = diskOffsets[0];
2022-05-03 05:36:37 +00:00
2016-08-14 08:41:19 +00:00
for (int i = 0; i < diskBlocks.length; i++)
{
if (diskBlocks[i] != lastDisk || diskOffsets[i] != lastOffset + i - first)
{
int size = i - first;
if (lastDisk > 0)
2022-05-03 05:36:37 +00:00
lines.add (String.format ("%03X - %03X %03X %d %03X - %03X", first, i - 1, size,
lastDisk, lastOffset, lastOffset + size - 1));
2016-08-14 08:41:19 +00:00
else
lines.add (String.format ("%03X - %03X %03X", first, i - 1, size));
first = i;
lastDisk = diskBlocks[i];
lastOffset = diskOffsets[i];
}
}
if (lastDisk > 0)
{
int max = diskBlocks.length;
int size = max - first;
2022-05-03 05:36:37 +00:00
lines.add (String.format ("%03X - %03X %03X %d %03X - %03X", first, max - 1, size,
lastDisk, lastOffset, lastOffset + size - 1));
2016-08-14 08:41:19 +00:00
}
for (int i = lines.size () - 1; i >= 0; i--)
{
String line = lines.get (i);
if (line.length () > 20)
break;
lines.remove (i);
}
2022-05-03 05:36:37 +00:00
text.append (String.format (" %s %s%n %s %s%n", heading, heading, underline,
underline));
2016-08-14 08:41:19 +00:00
int offset = (lines.size () + 1) / 2;
int pairs = lines.size () / 2;
for (int i = 0; i < pairs; i++)
2022-05-03 05:36:37 +00:00
text.append (String.format (" %-35s %s%n", lines.get (i), lines.get (i + offset)));
2016-08-14 08:41:19 +00:00
if (offset != pairs)
text.append (String.format (" %s%n", lines.get (pairs)));
2022-05-28 06:19:37 +00:00
// show gaps
if (false)
for (int i = 0; i < 0x22C; i++)
if (diskBlocks[i] == 0)
text.append (String.format ("%04X %3d %3d%n", i, diskBlocks[i], diskOffsets[i]));
2016-08-14 08:41:19 +00:00
return text.toString ();
}
2020-02-11 07:29:55 +00:00
// ---------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
private class DiskRecord
2020-02-11 07:29:55 +00:00
// ---------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
{
int diskNumber;
int totDiskSegments;
2022-05-03 05:36:37 +00:00
List<DiskSegment> diskSegments;
2016-08-14 08:41:19 +00:00
public DiskRecord (byte[] buffer, int ptr)
{
diskNumber = Utility.getShort (buffer, ptr);
2022-05-03 05:36:37 +00:00
totDiskSegments = Utility.getShort (buffer, ptr + 2);
diskSegments = new ArrayList<> (totDiskSegments);
2016-08-14 08:41:19 +00:00
ptr += 4;
for (int i = 0; i < totDiskSegments; i++)
{
diskSegments.add (new DiskSegment (buffer, ptr));
ptr += 6;
}
}
int size ()
{
return 4 + diskSegments.size () * 6;
}
@Override
public String toString ()
{
StringBuilder text = new StringBuilder ();
text.append (String.format ("Disk number.... %04X%n", diskNumber));
text.append (String.format ("Segments....... %04X%n%n", totDiskSegments));
2022-05-03 05:36:37 +00:00
text.append (String.format (" Seg Physical Logical Size Gap%n"));
text.append (String.format (" --- ----------- ----------- ---- ----%n"));
2016-08-14 08:41:19 +00:00
int count = 1;
int last = 0;
int skip = 0;
2022-05-03 05:36:37 +00:00
for (DiskSegment diskSegment : diskSegments)
2016-08-14 08:41:19 +00:00
{
2022-05-03 05:36:37 +00:00
if (diskSegment.logicalBlock > last)
2016-08-14 08:41:19 +00:00
{
2022-05-03 05:36:37 +00:00
int end = diskSegment.logicalBlock - 1;
2016-08-14 08:41:19 +00:00
skip = end - last + 1;
}
2022-05-03 05:36:37 +00:00
last = diskSegment.logicalBlock + diskSegment.segmentLength;
text.append (String.format (" %02X %s %04X%n", count++, diskSegment, skip));
2016-08-14 08:41:19 +00:00
}
return text.toString ();
}
}
2020-02-11 07:29:55 +00:00
// ---------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
private class DiskSegment
2020-02-11 07:29:55 +00:00
// ---------------------------------------------------------------------------------//
2016-08-14 08:41:19 +00:00
{
int logicalBlock;
int physicalBlock;
int segmentLength;
public DiskSegment (byte[] buffer, int ptr)
{
logicalBlock = Utility.getShort (buffer, ptr);
physicalBlock = Utility.getShort (buffer, ptr + 2);
segmentLength = Utility.getShort (buffer, ptr + 4);
2016-08-14 08:41:19 +00:00
}
@Override
public String toString ()
{
2022-05-03 05:36:37 +00:00
return String.format (" %04X - %04X %04X - %04X %04X", physicalBlock,
(physicalBlock + segmentLength - 1), logicalBlock, (logicalBlock + segmentLength - 1),
segmentLength);
2016-08-14 08:41:19 +00:00
}
}
}