From fc50481a58d41386f3ab16b860bfc205621dbcea Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Fri, 5 Feb 2016 11:23:53 +1100 Subject: [PATCH] show extra bytes for binary files --- resources/buildNumber | 3 - .../diskbrowser/applefile/AbstractFile.java | 4 + .../applefile/AssemblerProgram.java | 77 ++++++++++++++----- .../diskbrowser/dos/AbstractCatalogEntry.java | 48 ++++++++---- .../diskbrowser/prodos/CatalogEntry.java | 64 +++++++-------- .../diskbrowser/prodos/FileEntry.java | 44 +++++++---- 6 files changed, 156 insertions(+), 84 deletions(-) delete mode 100755 resources/buildNumber diff --git a/resources/buildNumber b/resources/buildNumber deleted file mode 100755 index de965d8..0000000 --- a/resources/buildNumber +++ /dev/null @@ -1,3 +0,0 @@ -#Build Number for ANT. Do not edit! -#Mon Dec 14 07:20:11 AEDT 2015 -build.number=633 diff --git a/src/com/bytezone/diskbrowser/applefile/AbstractFile.java b/src/com/bytezone/diskbrowser/applefile/AbstractFile.java index ff002b7..2b33e7f 100755 --- a/src/com/bytezone/diskbrowser/applefile/AbstractFile.java +++ b/src/com/bytezone/diskbrowser/applefile/AbstractFile.java @@ -53,15 +53,19 @@ public abstract class AbstractFile implements DataSource text.append (hb.title + "\n\n"); text.append (HexFormatter.format (buffer, hb.ptr, hb.size) + "\n\n"); } + text.deleteCharAt (text.length () - 1); text.deleteCharAt (text.length () - 1); return text.toString (); } + if (buffer == null || buffer.length == 0) return "No buffer"; + if (buffer.length <= 99999) return HexFormatter.format (buffer, 0, buffer.length); + return HexFormatter.format (buffer, 0, 99999); } diff --git a/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java b/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java index 4a329f4..0aab4fb 100755 --- a/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java +++ b/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java @@ -9,13 +9,19 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import com.bytezone.diskbrowser.HexFormatter; import com.bytezone.diskbrowser.gui.DiskBrowser; public class AssemblerProgram extends AbstractFile { + private static Map equates; + private final int loadAddress; private int executeOffset; - private static Map equates; + + private byte[] extraBuffer; + // private int offset; + // private int length; public AssemblerProgram (String name, byte[] buffer, int address) { @@ -32,6 +38,39 @@ public class AssemblerProgram extends AbstractFile this.executeOffset = executeOffset; } + public void setExtraBuffer (byte[] fullBuffer, int offset, int length) + { + this.extraBuffer = new byte[length]; + System.arraycopy (fullBuffer, offset, extraBuffer, 0, length); + } + + @Override + public String getHexDump () + { + String text = super.getHexDump (); + + if (extraBuffer == null) + return text; + + return text + "\n\n" + + HexFormatter.format (extraBuffer, 0, extraBuffer.length, buffer.length); + } + + @Override + public String getAssembler () + { + String text = super.getAssembler (); + + if (extraBuffer == null) + return text; + + String extraName = String.format ("%s (extra)", name); + AssemblerProgram assemblerProgram = + new AssemblerProgram (extraName, extraBuffer, buffer.length); + + return text + "\n\n" + assemblerProgram.getText (); + } + @Override public String getText () { @@ -45,10 +84,10 @@ public class AssemblerProgram extends AbstractFile pgm.append (String.format ("Entry : $%04X%n", (loadAddress + executeOffset))); pgm.append (String.format ("%n")); - return pgm.append (getStringBuilder ()).toString (); + return pgm.append (getStringBuilder2 ()).toString (); } - public StringBuilder getStringBuilder () + private StringBuilder getStringBuilder () { if (true) return getStringBuilder2 (); @@ -58,7 +97,8 @@ public class AssemblerProgram extends AbstractFile int ptr = executeOffset; int address = loadAddress + executeOffset; - // if the assembly doesn't start at the beginning, just dump the bytes that are skipped + // if the assembly doesn't start at the beginning, just dump the bytes that + // are skipped for (int i = 0; i < executeOffset; i++) pgm.append (String.format ("%04X: %02X%n", (loadAddress + i), buffer[i])); @@ -88,7 +128,7 @@ public class AssemblerProgram extends AbstractFile } if (cmd.target > 0 - && (cmd.target < loadAddress - 1 || cmd.target > (loadAddress + buffer.length))) + && (cmd.target < loadAddress - 1 || cmd.target > (loadAddress + buffer.length))) { while (line.length () < 40) line.append (" "); @@ -115,12 +155,13 @@ public class AssemblerProgram extends AbstractFile return pgm; } - public StringBuilder getStringBuilder2 () + private StringBuilder getStringBuilder2 () { StringBuilder pgm = new StringBuilder (); List lines = getLines (); - // if the assembly doesn't start at the beginning, just dump the bytes that are skipped + // if the assembly doesn't start at the beginning, just dump the bytes that + // are skipped for (int i = 0; i < executeOffset; i++) pgm.append (String.format (" %04X: %02X%n", (loadAddress + i), buffer[i])); @@ -128,7 +169,8 @@ public class AssemblerProgram extends AbstractFile { StringBuilder line = new StringBuilder (); - line.append (String.format ("%3.3s %04X: %02X ", getArrow (cmd), cmd.address, cmd.value)); + line.append (String.format ("%3.3s %04X: %02X ", getArrow (cmd), cmd.address, + cmd.value)); if (cmd.size > 1) line.append (String.format ("%02X ", cmd.operand1)); @@ -146,7 +188,7 @@ public class AssemblerProgram extends AbstractFile } if (cmd.target > 0 - && (cmd.target < loadAddress - 1 || cmd.target > (loadAddress + buffer.length))) + && (cmd.target < loadAddress - 1 || cmd.target > (loadAddress + buffer.length))) { while (line.length () < 40) line.append (" "); @@ -174,7 +216,8 @@ public class AssemblerProgram extends AbstractFile private List getLines () { List lines = new ArrayList (); - Map linesMap = new HashMap (); + Map linesMap = + new HashMap (); List targets = new ArrayList (); int ptr = executeOffset; @@ -195,7 +238,7 @@ public class AssemblerProgram extends AbstractFile cmd.size = 1; if (cmd.target >= loadAddress && cmd.target < (loadAddress + buffer.length) - && (cmd.value == 0x4C || cmd.value == 0x6C || cmd.value == 0x20)) + && (cmd.value == 0x4C || cmd.value == 0x6C || cmd.value == 0x20)) targets.add (cmd.target); if (cmd.offset != 0) targets.add (cmd.address + cmd.offset + 2); @@ -220,7 +263,7 @@ public class AssemblerProgram extends AbstractFile if (cmd.value == 0x4C || cmd.value == 0x6C || cmd.value == 0x60 || cmd.offset != 0) arrow = "<--"; if (cmd.value == 0x20 && // JSR - cmd.target >= loadAddress && cmd.target < (loadAddress + buffer.length)) + cmd.target >= loadAddress && cmd.target < (loadAddress + buffer.length)) arrow = "<--"; if (cmd.isTarget) if (arrow.isEmpty ()) @@ -230,18 +273,12 @@ public class AssemblerProgram extends AbstractFile return arrow; } - @Override - public String getAssembler () - { - return getStringBuilder ().toString (); - } - private void getEquates () { equates = new HashMap (); DataInputStream inputEquates = - new DataInputStream (DiskBrowser.class.getClassLoader () - .getResourceAsStream ("com/bytezone/diskbrowser/applefile/equates.txt")); + new DataInputStream (DiskBrowser.class.getClassLoader () + .getResourceAsStream ("com/bytezone/diskbrowser/applefile/equates.txt")); BufferedReader in = new BufferedReader (new InputStreamReader (inputEquates)); String line; diff --git a/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java b/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java index ab895af..abc14b1 100644 --- a/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java +++ b/src/com/bytezone/diskbrowser/dos/AbstractCatalogEntry.java @@ -27,7 +27,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource protected final List dataSectors = new ArrayList (); protected final List tsSectors = new ArrayList (); - public AbstractCatalogEntry (DosDisk dosDisk, DiskAddress catalogSector, byte[] entryBuffer) + public AbstractCatalogEntry (DosDisk dosDisk, DiskAddress catalogSector, + byte[] entryBuffer) { this.dosDisk = dosDisk; this.disk = dosDisk.getDisk (); @@ -58,9 +59,8 @@ abstract class AbstractCatalogEntry implements AppleFileSource name = getName ("", entryBuffer); // CATALOG command only formats the LO byte - see Beneath Apple DOS pp4-6 - String base = - String.format ("%s%s %03d ", (locked) ? "*" : " ", getFileType (), - (entryBuffer[33] & 0xFF)); + String base = String.format ("%s%s %03d ", (locked) ? "*" : " ", getFileType (), + (entryBuffer[33] & 0xFF)); catalogName = getName (base, entryBuffer); } @@ -140,6 +140,9 @@ abstract class AbstractCatalogEntry implements AppleFileSource try { + byte[] exactBuffer; + byte[] extraBuffer = new byte[0]; + switch (this.fileType) { case Text: @@ -148,12 +151,14 @@ abstract class AbstractCatalogEntry implements AppleFileSource else appleFile = new TextFile (name, buffer); break; + case IntegerBasic: reportedLength = HexFormatter.intValue (buffer[0], buffer[1]); - byte[] exactBuffer = new byte[reportedLength]; + exactBuffer = new byte[reportedLength]; System.arraycopy (buffer, 2, exactBuffer, 0, reportedLength); appleFile = new IntegerBasicProgram (name, exactBuffer); break; + case ApplesoftBasic: reportedLength = HexFormatter.intValue (buffer[0], buffer[1]); exactBuffer = new byte[reportedLength]; @@ -163,8 +168,9 @@ abstract class AbstractCatalogEntry implements AppleFileSource // appleFile = new ApplesoftBasicProgram (name, exactBuffer); appleFile = new BasicProgram (name, exactBuffer); break; - case Binary: // binary file - case Relocatable: // relocatable binary file + + case Binary: // binary file + case Relocatable: // relocatable binary file if (buffer.length == 0) appleFile = new AssemblerProgram (name, buffer, 0); else @@ -174,15 +180,21 @@ abstract class AbstractCatalogEntry implements AppleFileSource if (reportedLength == 0) { System.out.println (name.trim () + " reported length : 0 - reverting to " - + (buffer.length - 4)); + + (buffer.length - 4)); reportedLength = buffer.length - 4; } // buffer is a multiple of the block size, so it usually needs to be reduced if ((reportedLength + 4) <= buffer.length) + { exactBuffer = new byte[reportedLength]; + // extraBuffer = new byte[buffer.length - reportedLength - 4]; + // System.arraycopy (buffer, reportedLength + 4, extraBuffer, 0, + // extraBuffer.length); + } else - exactBuffer = new byte[buffer.length - 4]; // reported length is too long + exactBuffer = new byte[buffer.length - 4]; // reported length is too long + System.arraycopy (buffer, 4, exactBuffer, 0, exactBuffer.length); if (ShapeTable.isShapeTable (exactBuffer)) @@ -192,7 +204,7 @@ abstract class AbstractCatalogEntry implements AppleFileSource else if (loadAddress == 0x2000 || loadAddress == 0x4000) { if ((reportedLength > 0x1F00 && reportedLength <= 0x4000) - || ((name.equals ("FLY LOGO") && reportedLength == 0x14FA))) + || ((name.equals ("FLY LOGO") && reportedLength == 0x14FA))) appleFile = new HiResImage (name, exactBuffer); // else if // appleFile = new HiResImage (name, unscrunch (exactBuffer)); @@ -202,24 +214,34 @@ abstract class AbstractCatalogEntry implements AppleFileSource else if (name.endsWith (".S")) appleFile = new MerlinSource (name, exactBuffer); else + { appleFile = new AssemblerProgram (name, exactBuffer, loadAddress); + if (exactBuffer.length < buffer.length + 4) + ((AssemblerProgram) appleFile) + .setExtraBuffer (buffer, reportedLength + 4, + buffer.length - reportedLength - 4); + } } break; - case SS: // what is this? + + case SS: // what is this? System.out.println ("SS file"); appleFile = new DefaultAppleFile (name, buffer); break; - case AA: // what is this? + + case AA: // what is this? System.out.println ("AA file"); appleFile = new DefaultAppleFile (name, buffer); break; - case BB: // what is this? + + case BB: // what is this? int loadAddress = HexFormatter.intValue (buffer[0], buffer[1]); reportedLength = HexFormatter.intValue (buffer[2], buffer[3]); exactBuffer = new byte[reportedLength]; System.arraycopy (buffer, 4, exactBuffer, 0, reportedLength); appleFile = new SimpleText2 (name, exactBuffer, loadAddress); break; + default: System.out.println ("Unknown file type : " + fileType); appleFile = new DefaultAppleFile (name, buffer); diff --git a/src/com/bytezone/diskbrowser/prodos/CatalogEntry.java b/src/com/bytezone/diskbrowser/prodos/CatalogEntry.java index 94064c6..5b734c5 100755 --- a/src/com/bytezone/diskbrowser/prodos/CatalogEntry.java +++ b/src/com/bytezone/diskbrowser/prodos/CatalogEntry.java @@ -12,38 +12,40 @@ import com.bytezone.diskbrowser.disk.FormattedDisk; abstract class CatalogEntry implements AppleFileSource { - FormattedDisk parentDisk; - DirectoryHeader parentDirectory; - String name; - int storageType; - GregorianCalendar created; - int version; - int minVersion; - int access; - List dataBlocks = new ArrayList (); - Disk disk; + FormattedDisk parentDisk; + DirectoryHeader parentDirectory; + String name; + int storageType; + GregorianCalendar created; + int version; + int minVersion; + int access; + List dataBlocks = new ArrayList (); + Disk disk; - public CatalogEntry (ProdosDisk parentDisk, byte[] entryBuffer) - { - this.parentDisk = parentDisk; - this.disk = parentDisk.getDisk (); - name = HexFormatter.getString (entryBuffer, 1, entryBuffer[0] & 0x0F); - storageType = (entryBuffer[0] & 0xF0) >> 4; - created = HexFormatter.getAppleDate (entryBuffer, 24); - version = HexFormatter.intValue (entryBuffer[28]); - minVersion = HexFormatter.intValue (entryBuffer[29]); - access = HexFormatter.intValue (entryBuffer[30]); - } + public CatalogEntry (ProdosDisk parentDisk, byte[] entryBuffer) + { + this.parentDisk = parentDisk; + this.disk = parentDisk.getDisk (); + name = HexFormatter.getString (entryBuffer, 1, entryBuffer[0] & 0x0F); + storageType = (entryBuffer[0] & 0xF0) >> 4; + created = HexFormatter.getAppleDate (entryBuffer, 24); + version = HexFormatter.intValue (entryBuffer[28]); + minVersion = HexFormatter.intValue (entryBuffer[29]); + access = HexFormatter.intValue (entryBuffer[30]); + } - public String getUniqueName () - { - if (parentDirectory == null) - return name; - return parentDirectory.getUniqueName () + "/" + name; - } + @Override + public String getUniqueName () + { + if (parentDirectory == null) + return name; + return parentDirectory.getUniqueName () + "/" + name; + } - public FormattedDisk getFormattedDisk () - { - return parentDisk; - } + @Override + public FormattedDisk getFormattedDisk () + { + return parentDisk; + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/prodos/FileEntry.java b/src/com/bytezone/diskbrowser/prodos/FileEntry.java index e31528f..d180830 100755 --- a/src/com/bytezone/diskbrowser/prodos/FileEntry.java +++ b/src/com/bytezone/diskbrowser/prodos/FileEntry.java @@ -32,7 +32,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants private boolean invalid; public FileEntry (ProdosDisk fDisk, byte[] entryBuffer, DirectoryHeader parent, - int parentBlock) + int parentBlock) { super (fDisk, entryBuffer); this.parentDirectory = parent; @@ -265,13 +265,20 @@ class FileEntry extends CatalogEntry implements ProdosConstants file = new SimpleText (name, exactBuffer); else if (HiResImage.isGif (exactBuffer)) file = new HiResImage (name, exactBuffer); - else if ((endOfFile == 0x1FF8 || endOfFile == 0x1FFF || endOfFile == 0x2000 || endOfFile == 0x4000) - && (auxType == 0x1FFF || auxType == 0x2000 || auxType == 0x4000)) + else if ((endOfFile == 0x1FF8 || endOfFile == 0x1FFF || endOfFile == 0x2000 + || endOfFile == 0x4000) + && (auxType == 0x1FFF || auxType == 0x2000 || auxType == 0x4000)) file = new HiResImage (name, exactBuffer); else if (endOfFile == 38400 && name.startsWith ("LVL.")) file = new LodeRunner (name, exactBuffer); else + { file = new AssemblerProgram (name, exactBuffer, auxType); + if (exactBuffer.length < buffer.length) + ((AssemblerProgram) file) + .setExtraBuffer (buffer, exactBuffer.length, + buffer.length - exactBuffer.length); + } break; case FILE_TYPE_TEXT: assert auxType == 0; // auxType > 0 handled above @@ -288,9 +295,8 @@ class FileEntry extends CatalogEntry implements ProdosConstants break; case FILE_TYPE_DIRECTORY: VolumeDirectoryHeader vdh = ((ProdosDisk) parentDisk).vdh; - file = - new ProdosDirectory (parentDisk, name, buffer, vdh.totalBlocks, - vdh.freeBlocks, vdh.usedBlocks); + file = new ProdosDirectory (parentDisk, name, buffer, vdh.totalBlocks, + vdh.freeBlocks, vdh.usedBlocks); break; case FILE_TYPE_APPLESOFT_BASIC_VARS: if (endOfFile == 0) @@ -328,9 +334,8 @@ class FileEntry extends CatalogEntry implements ProdosConstants default: System.out.format ("Unknown file type : %02X%n", fileType); if (fileType == 0xB3) - file = - new DefaultAppleFile (name, exactBuffer, - "S16 Apple IIgs Application Program"); + file = new DefaultAppleFile (name, exactBuffer, + "S16 Apple IIgs Application Program"); else file = new DefaultAppleFile (name, exactBuffer); } @@ -370,7 +375,8 @@ class FileEntry extends CatalogEntry implements ProdosConstants byte[] mainIndexBuffer = disk.readSector (keyPtr); for (int i = 0; i < 256; i++) { - int indexBlock = HexFormatter.intValue (mainIndexBuffer[i], mainIndexBuffer[i + 256]); + int indexBlock = + HexFormatter.intValue (mainIndexBuffer[i], mainIndexBuffer[i + 256]); if (indexBlock > 0) logicalBlock = readIndexBlock (indexBlock, addresses, buffers, logicalBlock); else @@ -378,7 +384,8 @@ class FileEntry extends CatalogEntry implements ProdosConstants if (addresses.size () > 0) { byte[] tempBuffer = disk.readSectors (addresses); - buffers.add (new TextBuffer (tempBuffer, auxType, logicalBlock - addresses.size ())); + buffers.add (new TextBuffer (tempBuffer, auxType, + logicalBlock - addresses.size ())); addresses.clear (); } logicalBlock += 256; @@ -497,7 +504,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants } private int readIndexBlock (int indexBlock, List addresses, - List buffers, int logicalBlock) + List buffers, int logicalBlock) { byte[] indexBuffer = disk.readSector (indexBlock); for (int j = 0; j < 256; j++) @@ -508,7 +515,8 @@ class FileEntry extends CatalogEntry implements ProdosConstants else if (addresses.size () > 0) { byte[] tempBuffer = disk.readSectors (addresses); - buffers.add (new TextBuffer (tempBuffer, auxType, logicalBlock - addresses.size ())); + buffers + .add (new TextBuffer (tempBuffer, auxType, logicalBlock - addresses.size ())); addresses.clear (); } logicalBlock++; @@ -549,12 +557,14 @@ class FileEntry extends CatalogEntry implements ProdosConstants // String locked = (access == 0x01) ? "*" : " "; String locked = (access == 0x00) ? "*" : " "; if (true) - return String.format ("%s %03d %s", ProdosConstants.fileTypes[fileType], blocksUsed, - locked) + name; + return String.format ("%s %03d %s", ProdosConstants.fileTypes[fileType], + blocksUsed, locked) + + name; String timeC = created == null ? "" : ProdosDisk.df.format (created.getTime ()); String timeF = modified == null ? "" : ProdosDisk.df.format (modified.getTime ()); return String.format ("%s %s%-30s %3d %,10d %15s %15s", - ProdosConstants.fileTypes[fileType], locked, parentDirectory.name - + "/" + name, blocksUsed, endOfFile, timeC, timeF); + ProdosConstants.fileTypes[fileType], locked, + parentDirectory.name + "/" + name, blocksUsed, endOfFile, timeC, + timeF); } } \ No newline at end of file