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;
|
2020-06-26 03:29:46 +00:00
|
|
|
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);
|
|
|
|
|
2021-05-19 08:13:17 +00:00
|
|
|
checkByte = Utility.getShort (buffer, 0);
|
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)
|
|
|
|
addLogicalBlock ((byte) diskRecord.diskNumber, diskSegment);
|
|
|
|
}
|
|
|
|
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-08-14 08:41:19 +00:00
|
|
|
private void addLogicalBlock (byte disk, DiskSegment diskSegment)
|
2020-02-11 07:29:55 +00:00
|
|
|
// ---------------------------------------------------------------------------------//
|
2016-08-14 08:41:19 +00:00
|
|
|
{
|
|
|
|
int lo = diskSegment.logicalBlock;
|
|
|
|
int hi = diskSegment.logicalBlock + diskSegment.segmentLength;
|
|
|
|
|
|
|
|
for (int i = lo, count = 0; i < hi; i++, count++)
|
|
|
|
// if (diskBlocks[i] == 0) // doesn't matter either way
|
|
|
|
{
|
|
|
|
diskBlocks[i] = disk;
|
|
|
|
diskOffsets[i] = diskSegment.physicalBlock + count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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];
|
2016-08-22 10:54:03 +00:00
|
|
|
// byte[] key1 = { 0x55, 0x55, 0x15, 0x55 };
|
|
|
|
// byte[] key2 = { 0x00, 0x00, 0x01, 0x41 };
|
|
|
|
// byte[] key3 = { 0x01, 0x00, 0x01, 0x41 };
|
|
|
|
// byte[] key4 = { 0x00, 0x00, 0x15, 0x55 };
|
2016-08-14 08:41:19 +00:00
|
|
|
|
|
|
|
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-23 05:20:04 +00:00
|
|
|
// if (da.getBlock () == 0x126)
|
|
|
|
// System.out.println (HexFormatter.format (buffer));
|
2016-08-22 10:54:03 +00:00
|
|
|
// if (Utility.find (temp, key1))
|
|
|
|
// if (Utility.find (temp, key2))
|
|
|
|
// if (Utility.find (temp, key3))
|
|
|
|
// if (Utility.find (temp, key4))
|
|
|
|
// System.out.println (da);
|
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];
|
|
|
|
for (int i = 0; i < diskBlocks.length; i++)
|
|
|
|
{
|
|
|
|
if (diskBlocks[i] != lastDisk || diskOffsets[i] != lastOffset + i - first)
|
|
|
|
{
|
|
|
|
int size = i - first;
|
|
|
|
if (lastDisk > 0)
|
|
|
|
lines.add (String.format ("%03X - %03X %03X %d %03X - %03X", first,
|
|
|
|
i - 1, size, lastDisk, lastOffset, lastOffset + size - 1));
|
|
|
|
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;
|
|
|
|
lines.add (String.format ("%03X - %03X %03X %d %03X - %03X", first, max - 1,
|
|
|
|
size, lastDisk, lastOffset, lastOffset + size - 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = lines.size () - 1; i >= 0; i--)
|
|
|
|
{
|
|
|
|
String line = lines.get (i);
|
|
|
|
if (line.length () > 20)
|
|
|
|
break;
|
|
|
|
lines.remove (i);
|
|
|
|
}
|
|
|
|
|
|
|
|
text.append (String.format (" %s %s%n %s %s%n", heading, heading,
|
|
|
|
underline, underline));
|
|
|
|
int offset = (lines.size () + 1) / 2;
|
|
|
|
// boolean oddLines = lines.size () % 2 == 1;
|
|
|
|
int pairs = lines.size () / 2;
|
|
|
|
|
|
|
|
for (int i = 0; i < pairs; i++)
|
|
|
|
{
|
|
|
|
text.append (
|
|
|
|
String.format (" %-35s %s%n", lines.get (i), lines.get (i + offset)));
|
|
|
|
}
|
|
|
|
if (offset != pairs)
|
|
|
|
text.append (String.format (" %s%n", lines.get (pairs)));
|
|
|
|
|
|
|
|
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;
|
2020-02-02 10:17:49 +00:00
|
|
|
List<DiskSegment> diskSegments = new ArrayList<> ();
|
2016-08-14 08:41:19 +00:00
|
|
|
|
|
|
|
public DiskRecord (byte[] buffer, int ptr)
|
|
|
|
{
|
2021-05-19 08:13:17 +00:00
|
|
|
diskNumber = Utility.getShort (buffer, ptr);
|
2020-06-26 03:29:46 +00:00
|
|
|
totDiskSegments = Utility.intValue (buffer[ptr + 2], buffer[ptr + 4]);
|
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));
|
|
|
|
text.append (String.format (" Seg Skip Size Logical Physical%n"));
|
|
|
|
text.append (String.format (" --- ---- ---- ----------- -----------%n"));
|
|
|
|
|
|
|
|
int count = 1;
|
|
|
|
int last = 0;
|
|
|
|
int skip = 0;
|
|
|
|
|
|
|
|
for (DiskSegment segment : diskSegments)
|
|
|
|
{
|
|
|
|
if (segment.logicalBlock > last)
|
|
|
|
{
|
|
|
|
int end = segment.logicalBlock - 1;
|
|
|
|
skip = end - last + 1;
|
|
|
|
}
|
|
|
|
last = segment.logicalBlock + segment.segmentLength;
|
|
|
|
text.append (String.format (" %02X %04X %s %n", count++, skip, segment));
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2021-05-19 08:13:17 +00:00
|
|
|
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 ()
|
|
|
|
{
|
|
|
|
return String.format (" %04X %04X - %04X %04X - %04X", segmentLength,
|
|
|
|
logicalBlock, (logicalBlock + segmentLength - 1), physicalBlock,
|
|
|
|
(physicalBlock + segmentLength - 1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|