dmolony-DiskBrowser/src/com/bytezone/diskbrowser/applefile/PascalSegment.java

134 lines
5.1 KiB
Java
Executable File

package com.bytezone.diskbrowser.applefile;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.FileFormatException;
import com.bytezone.diskbrowser.HexFormatter;
public class PascalSegment extends AbstractFile implements PascalConstants
{
int segmentNoHeader;
int segmentNoBody;
public final int blockNo;
public final int size;
List<PascalProcedure> procedures;
int segKind;
int textAddress;
int machineType;
int version;
int intrinsSegs1;
int intrinsSegs2;
int slot;
int totalProcedures;
public PascalSegment (String name, byte[] fullBuffer, int seq)
{
super (name, fullBuffer); // sets this.buffer to the full buffer temporarily
this.slot = seq;
this.blockNo = HexFormatter.intValue (fullBuffer[seq * 4], fullBuffer[seq * 4 + 1]);
this.size = HexFormatter.intValue (fullBuffer[seq * 4 + 2], fullBuffer[seq * 4 + 3]);
this.segmentNoHeader = fullBuffer[0x100 + seq * 2];
segKind =
HexFormatter.intValue (fullBuffer[0xC0 + seq * 2], fullBuffer[0xC0 + seq * 2 + 1]);
textAddress =
HexFormatter.intValue (fullBuffer[0xE0 + seq * 2], fullBuffer[0xE0 + seq * 2 + 1]);
int flags = fullBuffer[0x101 + seq * 2] & 0xFF;
machineType = flags & 0x0F;
version = (flags & 0xD0) >> 5;
intrinsSegs1 =
HexFormatter.intValue (fullBuffer[0x120 + seq * 4], fullBuffer[0x120 + seq * 4 + 1]);
intrinsSegs2 =
HexFormatter.intValue (fullBuffer[0x120 + seq * 4 + 2],
fullBuffer[0x120 + seq * 4 + 3]);
int offset = blockNo * 512;
if (offset < fullBuffer.length)
{
buffer = new byte[size]; // replaces this.buffer with the segment buffer only
System.arraycopy (fullBuffer, blockNo * 512, buffer, 0, size);
totalProcedures = buffer[size - 1] & 0xFF;
segmentNoBody = buffer[size - 2] & 0xFF;
if (segmentNoBody != segmentNoHeader)
System.out.println ("Segment number mismatch : " + segmentNoBody + " / "
+ segmentNoHeader);
}
else
{
System.out.println ("Error in blocksize for pascal disk");
throw new FileFormatException ("Error in PascalSegment");
}
}
private void buildProcedureList ()
{
procedures = new ArrayList<PascalProcedure> (totalProcedures);
for (int i = 1; i <= totalProcedures; i++)
procedures.add (new PascalProcedure (buffer, i));
}
public String toText ()
{
return String
.format (" %2d %02X %04X %,6d %-8s %-15s %3d %3d %d %d %d %d",
slot, blockNo, size, size, name, SegmentKind[segKind], textAddress,
segmentNoHeader, machineType, version, intrinsSegs1, intrinsSegs2);
}
@Override
public String getText ()
{
if (procedures == null)
buildProcedureList ();
StringBuilder text = new StringBuilder ();
String title = "Segment - " + name;
text.append (title + "\n"
+ "===============================".substring (0, title.length ()) + "\n\n");
String warning =
segmentNoBody == segmentNoHeader ? "" : " (" + segmentNoHeader + " in header)";
text.append (String.format ("Address........ %02X%n", blockNo));
text.append (String.format ("Length......... %04X%n", buffer.length));
text.append (String.format ("Machine type... %d%n", machineType));
text.append (String.format ("Version........ %d%n", version));
text.append (String.format ("Segment........ %d%s%n", segmentNoBody, warning));
text.append (String.format ("Total procs.... %d%n", procedures.size ()));
text.append ("\nProcedure Dictionary\n====================\n\n");
int len = procedures.size () * 2 + 2;
if (false)
text.append (HexFormatter.format (buffer, buffer.length - len, len) + "\n\n");
text.append ("Proc Offset Lvl Entry Exit Parm Data Proc header\n");
text.append ("---- ------ --- ----- ---- ---- ---- --------------------\n");
for (PascalProcedure procedure : procedures)
{
if (procedure.valid)
{
int address = size - procedure.slot * 2 - 2;
text.append (String
.format (" %2d %04X %3d %04X %04X %04X %04X (%04X - %04X = %04X)%n",
procedure.procedureNo, procedure.offset, procedure.procLevel,
procedure.codeStart, procedure.codeEnd, procedure.parmSize,
procedure.dataSize, address, procedure.offset, procedure.procOffset));
}
else
text.append (String.format (" %2d %04X%n", procedure.slot, procedure.offset));
}
text.append ("\nStrings\n=======\n");
for (PascalProcedure pp : procedures)
{
List<PascalCodeStatement> strings = pp.extractStrings ();
for (PascalCodeStatement cs : strings)
text.append (String.format (" %2d %04X %s%n", pp.procedureNo, cs.ptr, cs.text));
}
for (PascalProcedure procedure : procedures)
if (procedure.valid)
text.append (procedure);
return text.toString ();
}
}