2015-06-01 09:35:51 +00:00
|
|
|
package com.bytezone.diskbrowser.applefile;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.List;
|
|
|
|
|
2016-08-05 08:40:32 +00:00
|
|
|
import com.bytezone.diskbrowser.applefile.Relocator.MultiDiskAddress;
|
2016-02-24 21:11:14 +00:00
|
|
|
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
2016-08-03 11:32:47 +00:00
|
|
|
import com.bytezone.diskbrowser.utilities.Utility;
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-08-02 10:37:27 +00:00
|
|
|
public class PascalCode extends AbstractFile
|
|
|
|
implements PascalConstants, Iterable<PascalSegment>
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
2016-08-05 08:40:32 +00:00
|
|
|
private final List<PascalSegment> segments = new ArrayList<PascalSegment> (16);
|
|
|
|
private final String comment;
|
|
|
|
private final int blockOffset;
|
|
|
|
private final Relocator relocator;
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-08-02 10:37:27 +00:00
|
|
|
public static void print ()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < 216; i++)
|
|
|
|
System.out.printf ("%3d %d %3s %s%n", i + 128, PascalConstants.mnemonicSize[i],
|
2016-08-04 12:00:53 +00:00
|
|
|
PascalConstants.mnemonics[i], PascalConstants.descriptions[i]);
|
2016-08-02 10:37:27 +00:00
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-08-05 08:40:32 +00:00
|
|
|
public PascalCode (String name, byte[] buffer, int blockOffset, Relocator relocator)
|
2016-08-02 10:37:27 +00:00
|
|
|
{
|
|
|
|
super (name, buffer);
|
2016-08-05 08:40:32 +00:00
|
|
|
|
|
|
|
this.blockOffset = blockOffset;
|
|
|
|
this.relocator = relocator;
|
|
|
|
|
2016-08-02 10:37:27 +00:00
|
|
|
int nonameCounter = 0;
|
2016-08-03 11:32:47 +00:00
|
|
|
if (false)
|
|
|
|
{
|
2016-08-04 12:00:53 +00:00
|
|
|
// System.out.println (name);
|
2016-08-04 06:08:19 +00:00
|
|
|
// byte[] key = new byte[] { 0x38, 0x00, 0x0C, 0x1C };
|
|
|
|
byte[] key = new byte[] { 0x0F };
|
2016-08-03 11:32:47 +00:00
|
|
|
Utility.find (buffer, key);
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-08-03 11:32:47 +00:00
|
|
|
// Create segment list (up to 16 segments)
|
2016-08-02 10:37:27 +00:00
|
|
|
for (int i = 0; i < 16; i++)
|
|
|
|
{
|
2016-08-04 12:00:53 +00:00
|
|
|
String codeName = HexFormatter.getString (buffer, 0x40 + i * 8, 8).trim ();
|
2016-08-02 10:37:27 +00:00
|
|
|
int size = HexFormatter.intValue (buffer[i * 4 + 2], buffer[i * 4 + 3]);
|
2016-08-04 12:00:53 +00:00
|
|
|
if (codeName.length () == 0 && size > 0)
|
|
|
|
codeName = "<NULL" + ++nonameCounter + ">";
|
|
|
|
// System.out.printf ("%s %s %d %n", HexFormatter.getHexString (buffer, i * 4, 4),
|
2016-08-03 11:32:47 +00:00
|
|
|
// codeName, size);
|
2016-08-02 10:37:27 +00:00
|
|
|
if (size > 0)
|
2016-08-04 12:00:53 +00:00
|
|
|
segments.add (new PascalSegment (codeName, buffer, i));
|
2016-08-02 10:37:27 +00:00
|
|
|
}
|
|
|
|
comment = HexFormatter.getPascalString (buffer, 0x1B0);
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-08-02 10:37:27 +00:00
|
|
|
@Override
|
|
|
|
public String getText ()
|
|
|
|
{
|
|
|
|
StringBuilder text = new StringBuilder (getHeader ());
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-08-02 10:37:27 +00:00
|
|
|
text.append ("Segment Dictionary\n==================\n\n");
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-08-05 21:29:27 +00:00
|
|
|
text.append ("Slot Addr Blks Len Name Kind"
|
|
|
|
+ " Txt Seg Mch Ver I/S I/S D:Blk\n");
|
|
|
|
text.append ("---- ---- ---- ---- -------- ---------------"
|
|
|
|
+ " --- --- --- --- --- --- ---------------------\n");
|
2016-08-05 08:40:32 +00:00
|
|
|
|
2016-08-02 10:37:27 +00:00
|
|
|
for (PascalSegment segment : segments)
|
2016-08-05 08:40:32 +00:00
|
|
|
{
|
|
|
|
int sizeInBlocks = (segment.size - 1) / 512 + 1;
|
2016-08-05 21:29:27 +00:00
|
|
|
System.out.printf ("Seg: %-8s add: %03X%n", segment.name, segment.blockNo);
|
2016-08-05 08:40:32 +00:00
|
|
|
String multiDiskAddressText = "";
|
|
|
|
if (segment.segmentNoHeader == 1) // main segment
|
|
|
|
{
|
|
|
|
multiDiskAddressText = String.format ("1:%03X", (segment.blockNo + blockOffset));
|
|
|
|
}
|
|
|
|
else if (relocator != null)
|
|
|
|
{
|
2016-08-05 21:29:27 +00:00
|
|
|
int targetBlock = segment.blockNo + blockOffset;
|
|
|
|
List<MultiDiskAddress> addresses =
|
|
|
|
relocator.getMultiDiskAddress (segment.name, targetBlock, sizeInBlocks);
|
|
|
|
if (addresses.isEmpty ())
|
|
|
|
multiDiskAddressText = ".";
|
2016-08-05 08:40:32 +00:00
|
|
|
else
|
|
|
|
{
|
2016-08-05 21:29:27 +00:00
|
|
|
StringBuilder locations = new StringBuilder ();
|
|
|
|
for (MultiDiskAddress multiDiskAddress : addresses)
|
|
|
|
locations.append (multiDiskAddress.toString () + ", ");
|
|
|
|
if (locations.length () > 2)
|
2016-08-05 08:40:32 +00:00
|
|
|
{
|
2016-08-05 21:29:27 +00:00
|
|
|
locations.deleteCharAt (locations.length () - 1);
|
|
|
|
locations.deleteCharAt (locations.length () - 1);
|
2016-08-05 08:40:32 +00:00
|
|
|
}
|
2016-08-05 21:29:27 +00:00
|
|
|
multiDiskAddressText = locations.toString ();
|
2016-08-05 08:40:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
text.append (segment.toText (blockOffset, multiDiskAddressText) + "\n");
|
|
|
|
}
|
2016-08-02 10:37:27 +00:00
|
|
|
text.append ("\nComment : " + comment + "\n\n");
|
2016-08-05 21:29:27 +00:00
|
|
|
relocator.list ();
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-08-02 10:37:27 +00:00
|
|
|
return text.toString ();
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-08-02 10:37:27 +00:00
|
|
|
private String getHeader ()
|
|
|
|
{
|
|
|
|
return "Name : " + name + "\n\n";
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-08-02 10:37:27 +00:00
|
|
|
@Override
|
|
|
|
public Iterator<PascalSegment> iterator ()
|
|
|
|
{
|
|
|
|
return segments.iterator ();
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|