diff --git a/src/com/bytezone/diskbrowser/applefile/PascalCode.java b/src/com/bytezone/diskbrowser/applefile/PascalCode.java index 595c975..adc617c 100755 --- a/src/com/bytezone/diskbrowser/applefile/PascalCode.java +++ b/src/com/bytezone/diskbrowser/applefile/PascalCode.java @@ -29,7 +29,8 @@ public class PascalCode extends AbstractFile if (false) { System.out.println (name); - byte[] key = new byte[] { 0x38, 0x00, 0x0C, 0x1C }; + // byte[] key = new byte[] { 0x38, 0x00, 0x0C, 0x1C }; + byte[] key = new byte[] { 0x0F }; Utility.find (buffer, key); } @@ -64,10 +65,10 @@ public class PascalCode extends AbstractFile text.append ("Segment Dictionary\n==================\n\n"); - text.append ("Slot Addr Len Len Name Kind" - + " Text Seg# Mtyp Vers I/S\n"); - text.append ("---- ---- ----- ----- -------- ---------------" - + " ---- ---- ---- ---- ---\n"); + text.append ("Slot Addr Blks Len Len Name Kind" + + " Txt Seg Mch Ver I/S I/S\n"); + text.append ("---- ---- ---- ---- ----- -------- ---------------" + + " --- --- --- --- --- ---\n"); for (PascalSegment segment : segments) text.append (segment.toText () + "\n"); diff --git a/src/com/bytezone/diskbrowser/applefile/PascalProcedure.java b/src/com/bytezone/diskbrowser/applefile/PascalProcedure.java index ef9177d..5d9ace3 100755 --- a/src/com/bytezone/diskbrowser/applefile/PascalProcedure.java +++ b/src/com/bytezone/diskbrowser/applefile/PascalProcedure.java @@ -67,7 +67,7 @@ public class PascalProcedure while (ptr < max) { - System.out.printf ("ptr:%d, max:%d, buf:%d %n", ptr, max, buffer.length); + // System.out.printf ("ptr:%d, max:%d, buf:%d %n", ptr, max, buffer.length); if (ptr >= buffer.length || ptr < 0) { System.out.println ("Ptr outside buffer"); @@ -138,19 +138,18 @@ public class PascalProcedure StringBuilder text = new StringBuilder ("\nProcedure Header\n================\n\n"); if (false) - text.append (HexFormatter.format (buffer, procOffset + jumpTable, 2 - jumpTable) - + "\n\n"); + text.append ( + HexFormatter.format (buffer, procOffset + jumpTable, 2 - jumpTable) + "\n\n"); - text.append (String.format ("Level.......%5d %02X%n", procLevel, - procLevel & 0xFF)); + text.append ( + String.format ("Level.......%5d %02X%n", procLevel, procLevel & 0xFF)); text.append (String.format ("Proc no.....%5d %02X%n", procedureNo, procedureNo)); text.append (String.format ("Code entry..%5d %04X (%04X - %04X = %04X)%n", - codeStart, codeStart, (procOffset - 2), codeStart, - (procOffset - codeStart - 2))); + codeStart, codeStart, (procOffset - 2), codeStart, (procOffset - codeStart - 2))); text.append (String.format ("Code exit...%5d %04X", codeEnd, codeEnd)); if (codeEnd > 0) text.append (String.format (" (%04X - %04X = %04X)%n", (procOffset - 4), codeEnd, - (procOffset - codeEnd - 4))); + (procOffset - codeEnd - 4))); else text.append (String.format ("%n")); text.append (String.format ("Parm size...%5d %04X%n", parmSize, parmSize)); @@ -181,7 +180,7 @@ public class PascalProcedure { ptr = i - ((buffer[i + 1] & 0xFF) * 256 + (buffer[i] & 0xFF)); text.append (String.format ("%05X : %02X %02X --> %04X%n", i, buffer[i], - buffer[i + 1], ptr)); + buffer[i + 1], ptr)); } } } diff --git a/src/com/bytezone/diskbrowser/applefile/PascalSegment.java b/src/com/bytezone/diskbrowser/applefile/PascalSegment.java index 55a85b8..7e95981 100755 --- a/src/com/bytezone/diskbrowser/applefile/PascalSegment.java +++ b/src/com/bytezone/diskbrowser/applefile/PascalSegment.java @@ -11,7 +11,8 @@ public class PascalSegment extends AbstractFile implements PascalConstants private final int segmentNoHeader; private int segmentNoBody; - public final int blockNo; + public int blockNo; + public int newBlockNo; public final int size; private final int segKind; @@ -23,6 +24,19 @@ public class PascalSegment extends AbstractFile implements PascalConstants private final int slot; private int totalProcedures; private List procedures; + private static final List redirections = new ArrayList (); + + static + { + // somehow this should match the data in SYSTEM.RELOC + redirections.add (new Redirection ("WIZARDRY", 0x01, 0x1C66, 0x01)); + redirections.add (new Redirection ("KANJIREA", 0x013F, 0x104E, 0x10)); + redirections.add (new Redirection ("UTILITIE", 0x48, 0x1598, 0x19)); + redirections.add (new Redirection ("SHOPS", 0x53, 0x0BE2, 0x24)); + redirections.add (new Redirection ("CAMP", 0x70, 0x24CA, 0x2A)); + redirections.add (new Redirection ("DOCOPY", 0x83, 0x07A0, 0x3D)); + redirections.add (new Redirection ("DOCACHE", 0x87, 0x072E, 0x41)); + } public PascalSegment (String name, byte[] fullBuffer, int seq) { @@ -32,37 +46,48 @@ public class PascalSegment extends AbstractFile implements PascalConstants this.blockNo = HexFormatter.intValue (fullBuffer[seq * 4], fullBuffer[seq * 4 + 1]); this.size = HexFormatter.intValue (fullBuffer[seq * 4 + 2], fullBuffer[seq * 4 + 3]); + for (Redirection redirection : redirections) + if (redirection.matches (name, blockNo, size)) + { + newBlockNo = redirection.newOffset; + break; + } + segKind = HexFormatter.intValue (fullBuffer[0xC0 + seq * 2], - fullBuffer[0xC0 + seq * 2 + 1]); + fullBuffer[0xC0 + seq * 2 + 1]); textAddress = HexFormatter.intValue (fullBuffer[0xE0 + seq * 2], - fullBuffer[0xE0 + seq * 2 + 1]); + fullBuffer[0xE0 + seq * 2 + 1]); + // segment 1 is the main segment, 2-6 are used by the system, and 7 + // onwards is for our program this.segmentNoHeader = fullBuffer[0x100 + seq * 2] & 0xFF; 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]); + fullBuffer[0x120 + seq * 4 + 1]); intrinsSegs2 = HexFormatter.intValue (fullBuffer[0x120 + seq * 4 + 2], - fullBuffer[0x120 + seq * 4 + 3]); + fullBuffer[0x120 + seq * 4 + 3]); int offset = blockNo * 512; + if (newBlockNo > 0) + offset = newBlockNo * 512; // System.out.printf ("Seq:%d, block:%d, size:%d, seg:%d, kind:%d, address:%d %n", seq, // blockNo, size, segmentNoHeader, segKind, textAddress); // System.out.println (HexFormatter.format (fullBuffer)); if (offset < fullBuffer.length) { buffer = new byte[size]; // replaces this.buffer with the segment buffer only - System.arraycopy (fullBuffer, blockNo * 512, buffer, 0, size); + System.arraycopy (fullBuffer, offset, buffer, 0, size); totalProcedures = buffer[size - 1] & 0xFF; segmentNoBody = buffer[size - 2] & 0xFF; if (segmentNoHeader == 0) System.out.printf ("Zero segment header in %s seq %d%n", name, seq); else if (segmentNoBody != segmentNoHeader) - System.out.println ("Segment number mismatch : " + segmentNoBody + " / " - + segmentNoHeader); + System.out.println ( + "Segment number mismatch : " + segmentNoBody + " / " + segmentNoHeader); } else { @@ -82,10 +107,14 @@ public class PascalSegment extends AbstractFile implements PascalConstants public String toText () { - return String - .format (" %2d %02X %04X %,6d %-8s %-15s %3d %02X %d %d %d %d", - slot, blockNo, size, size, name, SegmentKind[segKind], textAddress, - segmentNoHeader, machineType, version, intrinsSegs1, intrinsSegs2); + int sizeInBlocks = (size - 1) / 512 + 1; + String newBlock = newBlockNo > 0 ? String.format ("%02X + %02X = %02X", newBlockNo, + sizeInBlocks, (newBlockNo + sizeInBlocks)) : ""; + return String.format ( + " %2d %02X %02X %04X %,6d %-8s %-15s%3d " + + "%02X %d %d %d %d %s", + slot, blockNo, sizeInBlocks, size, size, name, SegmentKind[segKind], textAddress, + segmentNoHeader, machineType, version, intrinsSegs1, intrinsSegs2, newBlock); } @Override @@ -114,18 +143,18 @@ public class PascalSegment extends AbstractFile implements PascalConstants 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"); + text.append ( + "---- ------ --- ----- ---- ---- ---- --------------------\n"); for (PascalProcedure procedure : procedures) { if (procedure.valid) { int address = size - procedure.slot * 2 - 2; - text.append (String - .format (" %3d %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)); + text.append (String.format ( + " %3d %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 (" %3d %04X%n", procedure.slot, procedure.offset)); @@ -136,8 +165,8 @@ public class PascalSegment extends AbstractFile implements PascalConstants { List strings = pp.extractStrings (); for (PascalCodeStatement cs : strings) - text.append (String.format (" %2d %04X %s%n", pp.procedureNo, cs.ptr, - cs.text)); + text.append ( + String.format (" %2d %04X %s%n", pp.procedureNo, cs.ptr, cs.text)); } for (PascalProcedure procedure : procedures) @@ -145,4 +174,25 @@ public class PascalSegment extends AbstractFile implements PascalConstants text.append (procedure); return text.toString (); } +} + +class Redirection +{ + int oldOffset; + int newOffset; + int length; + String name; + + public Redirection (String name, int oldOffset, int length, int newOffset) + { + this.name = name; + this.oldOffset = oldOffset; + this.newOffset = newOffset; + this.length = length; + } + + public boolean matches (String name, int offset, int length) + { + return this.name.equals (name) && this.oldOffset == offset && this.length == length; + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/applefile/Relocator.java b/src/com/bytezone/diskbrowser/applefile/Relocator.java index 6957d15..9639b2f 100644 --- a/src/com/bytezone/diskbrowser/applefile/Relocator.java +++ b/src/com/bytezone/diskbrowser/applefile/Relocator.java @@ -100,8 +100,9 @@ public class Relocator extends AbstractFile @Override public String toString () { - return String.format (" %04X %04X %04X %04X", logicalBlock, - physicalBlock, segmentLength, (physicalBlock - 0x46)); + return String.format (" %04X %04X %04X %04X %04X", + logicalBlock, physicalBlock, segmentLength, + (logicalBlock - 0x46), (physicalBlock - 0x46)); } } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/pascal/CatalogEntry.java b/src/com/bytezone/diskbrowser/pascal/CatalogEntry.java index af79c55..7eae848 100644 --- a/src/com/bytezone/diskbrowser/pascal/CatalogEntry.java +++ b/src/com/bytezone/diskbrowser/pascal/CatalogEntry.java @@ -30,16 +30,15 @@ abstract class CatalogEntry implements AppleFileSource firstBlock = HexFormatter.intValue (buffer[0], buffer[1]); lastBlock = HexFormatter.intValue (buffer[2], buffer[3]); fileType = HexFormatter.intValue (buffer[4], buffer[5]); - // fileType = buffer[4] & 0x0F; name = HexFormatter.getPascalString (buffer, 6); bytesUsedInLastBlock = HexFormatter.intValue (buffer[16], buffer[17]); Disk disk = parent.getDisk (); for (int i = firstBlock; i < lastBlock; i++) { - if (i >= 280) + if (i >= 0x118) { - System.out.printf ("CatalogEntry: block %04X >= 280%n", i); + System.out.printf ("CatalogEntry: block 0x%04X >= 0x0118%n", i); break; } blocks.add (disk.getDiskAddress (i)); diff --git a/src/com/bytezone/diskbrowser/pascal/FileEntry.java b/src/com/bytezone/diskbrowser/pascal/FileEntry.java index 9b80ed2..cc551d8 100644 --- a/src/com/bytezone/diskbrowser/pascal/FileEntry.java +++ b/src/com/bytezone/diskbrowser/pascal/FileEntry.java @@ -64,7 +64,10 @@ class FileEntry extends CatalogEntry switch (fileType) { case 2: - file = new PascalCode (name, buffer); + if (name.equals ("SYSTEM.INTERP")) + file = new AssemblerProgram (name, buffer, 0xD000); + else + file = new PascalCode (name, buffer); break; case 3: diff --git a/src/com/bytezone/diskbrowser/pascal/PascalDisk.java b/src/com/bytezone/diskbrowser/pascal/PascalDisk.java index 293dbfc..194c2e6 100755 --- a/src/com/bytezone/diskbrowser/pascal/PascalDisk.java +++ b/src/com/bytezone/diskbrowser/pascal/PascalDisk.java @@ -103,7 +103,7 @@ public class PascalDisk extends AbstractFormattedDisk fileEntries.add (fileEntry); DefaultMutableTreeNode node = new DefaultMutableTreeNode (fileEntry); - if (fileEntry.fileType == 2) // PascalCode + if (fileEntry.fileType == 2 && fileEntry.getDataSource () instanceof PascalCode) // PascalCode { node.setAllowsChildren (true); PascalCode pascalCode = (PascalCode) fileEntry.getDataSource ();