diff --git a/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java b/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java index fc051cd..ee716c9 100755 --- a/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java +++ b/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java @@ -23,7 +23,6 @@ public class AssemblerProgram extends AbstractFile private byte[] extraBuffer = new byte[0]; - // private TreeMap strings; private List entryPoints; private List stringLocations; @@ -249,13 +248,10 @@ public class AssemblerProgram extends AbstractFile StringBuilder text = new StringBuilder ("\n\nPossible strings:\n\n"); for (StringLocation stringLocation : stringLocations) { - if (stringLocation.zeroTerminated) - text.append (String.format ("%s %04X - %04X %s %s %n", - entryPoints.contains (stringLocation.offset + loadAddress) ? "*" : " ", - stringLocation.offset, stringLocation.offset + stringLocation.length, - stringLocation.toStatisticsString (), stringLocation)); - else - System.out.println (stringLocation); + int address = stringLocation.offset + loadAddress; + text.append (String.format ("%s %04X - %04X %s %n", + entryPoints.contains (stringLocation.offset + loadAddress) ? "*" : " ", address, + address + stringLocation.length, stringLocation)); } if (text.length () > 0) @@ -270,15 +266,16 @@ public class AssemblerProgram extends AbstractFile stringLocations = new ArrayList<> (); int start = 0; + int max = buffer.length - 2; for (int ptr = 0; ptr < buffer.length; ptr++) { if ((buffer[ptr] == (byte) 0xBD // LDA Absolute,X || buffer[ptr] == (byte) 0xB9 // LDA Absolute,Y || buffer[ptr] == (byte) 0xAD) // LDA Absolute - && (ptr + 2 < buffer.length)) + && (ptr < max)) { int address = Utility.getWord (buffer, ptr + 1); - if (address > loadAddress && address < loadAddress + buffer.length) + if (address >= loadAddress && address < loadAddress + buffer.length) entryPoints.add (address); } @@ -355,6 +352,7 @@ public class AssemblerProgram extends AbstractFile int offset; int length; boolean zeroTerminated; + boolean lowTerminated; boolean hasLengthByte; int digits; int letters; @@ -367,7 +365,10 @@ public class AssemblerProgram extends AbstractFile offset = first; length = last - offset + 1; - zeroTerminated = ++last < buffer.length && buffer[last] == 0; + int end = last + 1; + + zeroTerminated = end < buffer.length && buffer[end] == 0; + lowTerminated = end < buffer.length && buffer[end] >= 32 && buffer[end] < 127; hasLengthByte = first > 0 && (buffer[first] & 0xFF) == length; for (int i = offset; i < offset + length; i++) @@ -419,6 +420,8 @@ public class AssemblerProgram extends AbstractFile else text.append ((char) val); } + if (lowTerminated) + text.append ((char) buffer[offset + length]); return text.toString (); } diff --git a/src/com/bytezone/diskbrowser/applefile/IconFile.java b/src/com/bytezone/diskbrowser/applefile/IconFile.java index 3bb233d..5584583 100644 --- a/src/com/bytezone/diskbrowser/applefile/IconFile.java +++ b/src/com/bytezone/diskbrowser/applefile/IconFile.java @@ -13,25 +13,6 @@ import com.bytezone.diskbrowser.utilities.HexFormatter; public class IconFile extends AbstractFile implements ProdosConstants { - private static Palette palette = // - new Palette ("Virtual II", new int[] { 0x000000, // 0 black - 0xDD0033, // 1 magenta - 0x885500, // 2 brown (8) - 0xFF6600, // 3 orange (9) - 0x007722, // 4 dark green - 0x555555, // 5 grey1 - 0x11DD00, // 6 light green (C) - 0xFFFF00, // 7 yellow (D) - 0x000099, // 8 dark blue (2) - 0xDD22DD, // 9 purple (3) - 0xAAAAAA, // A grey2 - 0xFF9988, // B pink - 0x2222FF, // C med blue (6) - 0x66AAFF, // D light blue (7) - 0x44FF99, // E aqua - 0xFFFFFF // F white - }); - private final int iBlkNext; private final int iBlkID; private final int iBlkPath; @@ -53,11 +34,12 @@ public class IconFile extends AbstractFile implements ProdosConstants while (true) { int dataLen = HexFormatter.unsignedShort (buffer, ptr); - if (dataLen == 0 || (dataLen + ptr) > buffer.length) break; + Icon icon = new Icon (buffer, ptr); - icons.add (icon); + if (icon.smallImage != null) // didn't have an exception + icons.add (icon); ptr += dataLen; } @@ -77,8 +59,10 @@ public class IconFile extends AbstractFile implements ProdosConstants int columns = Math.min (icons.size (), 4); int rows = (icons.size () - 1) / columns + 1; - image = new BufferedImage (columns * maxWidth + 2 * base + (columns - 1) * gap, - rows * maxHeight + 2 * base + (rows - 1) * gap, BufferedImage.TYPE_INT_RGB); + image = new BufferedImage ( // + columns * maxWidth + 2 * base + (columns - 1) * gap, // + rows * maxHeight + 2 * base + (rows - 1) * gap, // + BufferedImage.TYPE_INT_RGB); Graphics2D graphics = image.createGraphics (); graphics.setBackground (Color.WHITE); @@ -100,6 +84,7 @@ public class IconFile extends AbstractFile implements ProdosConstants } } g2d.dispose (); + graphics.dispose (); } @Override @@ -212,7 +197,7 @@ public class IconFile extends AbstractFile implements ProdosConstants System.out.println (); } - if (iconType != 0 && iconType != 0x8000) + if (iconType != 0 && iconType != 0x8000 && iconType != 0xFFFF && iconType != 0x00FF) throw new InvalidImageException (String.format ("Bad icon type: %04X", iconType)); iconImage = new byte[iconSize]; @@ -223,7 +208,7 @@ public class IconFile extends AbstractFile implements ProdosConstants System.arraycopy (buffer, ptr + 8, iconImage, 0, iconSize); System.arraycopy (buffer, ptr + 8 + iconSize, iconMask, 0, iconSize); - int[] colours = palette.getColours (); + int[] colours = HiResImage.getPaletteFactory ().get (0).getColours (); image = new BufferedImage (iconWidth, iconHeight, BufferedImage.TYPE_INT_RGB); @@ -275,7 +260,7 @@ public class IconFile extends AbstractFile implements ProdosConstants /* Offset Color RGB Mini-Palette - + 0 Black 000 0 1 Blue 00F 1 2 Yellow FF0 2 @@ -284,7 +269,7 @@ public class IconFile extends AbstractFile implements ProdosConstants 5 Red D00 1 6 Green 0E0 2 7 White FFF 3 - + 8 Black 000 0 9 Blue 00F 1 10 Yellow FF0 2 @@ -293,18 +278,18 @@ public class IconFile extends AbstractFile implements ProdosConstants 13 Red D00 1 14 Green 0E0 2 15 White FFF 3 - + The displayMode word bits are defined as: - + Bit 0 selectedIconBit 1 = invert image before copying Bit 1 openIconBit 1 = copy light-gray pattern instead of image Bit 2 offLineBit 1 = AND light-gray pattern to image being copied Bits 3-7 reserved. Bits 8-11 foreground color to apply to black part of black & white icons Bits 12-15 background color to apply to white part of black & white icons - + Bits 0-2 can occur at once and are tested in the order 1-2-0. - + "Color is only applied to the black and white icons if bits 15-8 are not all 0. Colored pixels in an icon are inverted by black pixels becoming white and any other color of pixel becoming black." diff --git a/src/com/bytezone/diskbrowser/disk/AppleDisk.java b/src/com/bytezone/diskbrowser/disk/AppleDisk.java index 14375d1..3dbbb8d 100755 --- a/src/com/bytezone/diskbrowser/disk/AppleDisk.java +++ b/src/com/bytezone/diskbrowser/disk/AppleDisk.java @@ -155,7 +155,8 @@ public class AppleDisk implements Disk } else if (suffix.equalsIgnoreCase ("HDV")) { - this.blocks = (int) file.length () / 4096 * 8; // reduce blocks to a multiple of 8 + // this.blocks = (int) file.length () / 4096 * 8; // reduce blocks to a multiple of 8 + this.blocks = tracks * sectors; this.sectorSize = 512; this.trackSize = sectors * sectorSize; } @@ -193,7 +194,6 @@ public class AppleDisk implements Disk diskBuffer = new byte[blocks * sectorSize]; hasData = new boolean[blocks]; - // isMissing = new boolean[blocks]; if (debug) { @@ -415,7 +415,10 @@ public class AppleDisk implements Disk public byte[] readSector (DiskAddress da) { byte[] buffer = new byte[sectorSize]; - readBuffer (da, buffer, 0); + if (da == null) + System.out.println ("Disk address is null"); + else + readBuffer (da, buffer, 0); return buffer; } diff --git a/src/com/bytezone/diskbrowser/disk/AppleDiskAddress.java b/src/com/bytezone/diskbrowser/disk/AppleDiskAddress.java index 91ff5a6..c19da14 100755 --- a/src/com/bytezone/diskbrowser/disk/AppleDiskAddress.java +++ b/src/com/bytezone/diskbrowser/disk/AppleDiskAddress.java @@ -14,8 +14,16 @@ public class AppleDiskAddress implements DiskAddress this.owner = owner; this.block = block; int sectorsPerTrack = owner.getSectorsPerTrack (); - this.track = block / sectorsPerTrack; - this.sector = block % sectorsPerTrack; + if (sectorsPerTrack == 0) + { + track = 0; + sector = 0; + } + else + { + track = block / sectorsPerTrack; + sector = block % sectorsPerTrack; + } } public AppleDiskAddress (Disk owner, int track, int sector) diff --git a/src/com/bytezone/diskbrowser/disk/DiskFactory.java b/src/com/bytezone/diskbrowser/disk/DiskFactory.java index 6571bf0..8c3da9c 100755 --- a/src/com/bytezone/diskbrowser/disk/DiskFactory.java +++ b/src/com/bytezone/diskbrowser/disk/DiskFactory.java @@ -236,10 +236,8 @@ public class DiskFactory System.out.println ("Checking woz"); try { - // WozFileOld wozDisk = new WozFileOld (file); WozFile wozFile = new WozFile (file); - if (debug) - System.out.println (" Woz read"); + if (wozFile.getSectorsPerTrack () == 13) { AppleDisk appleDisk = new AppleDisk (wozFile, 35, 13); @@ -526,8 +524,14 @@ public class DiskFactory try { - // truncate the file if necessary - AppleDisk disk = new AppleDisk (file, (int) file.length () / 4096, 8); + // extend the file if necessary + int tracks = (int) (file.length () - 1) / 4096 + 1; + if (tracks * 4096 != file.length ()) + { + System.out.println ("*** extended ***"); // System Addons.hdv + // System.out.println (tracks); + } + AppleDisk disk = new AppleDisk (file, tracks, 8); if (ProdosDisk.isCorrectFormat (disk)) { if (debug) diff --git a/src/com/bytezone/diskbrowser/dos/DosDisk.java b/src/com/bytezone/diskbrowser/dos/DosDisk.java index e17903c..2a0d42c 100755 --- a/src/com/bytezone/diskbrowser/dos/DosDisk.java +++ b/src/com/bytezone/diskbrowser/dos/DosDisk.java @@ -235,6 +235,7 @@ public class DosDisk extends AbstractFormattedDisk { disk.setInterleave (0); int catalogBlocks = checkFormat (disk); + if (catalogBlocks > 3) return true; disk.setInterleave (1); @@ -243,19 +244,22 @@ public class DosDisk extends AbstractFormattedDisk if (cb2 > 3) return true; disk.setInterleave (2); - if (false) + if (true) { int cb3 = checkFormat (disk); if (cb3 > 3) return true; } + if (catalogBlocks > 0) { disk.setInterleave (1); return true; } + if (cb2 > 0) return true; + return false; } @@ -293,7 +297,7 @@ public class DosDisk extends AbstractFormattedDisk // if (buffer[1] != 0x11) // first catalog track // return 0; - if (buffer[53] != 16 && buffer[53] != 13) // tracks per sector + if (buffer[53] != 16 && buffer[53] != 13) // sectors per track { return 0; } @@ -325,7 +329,7 @@ public class DosDisk extends AbstractFormattedDisk do { if (!disk.isValidAddress (da)) - break; + return 0; if (catalogAddresses.contains (da)) { @@ -336,8 +340,8 @@ public class DosDisk extends AbstractFormattedDisk buffer = disk.readSector (da); if (!disk.isValidAddress (buffer[1], buffer[2])) { - System.out.printf ("Invalid address : %02X / %02X%n", buffer[1], buffer[2]); - break; + // System.out.printf ("Invalid address : %02X / %02X%n", buffer[1], buffer[2]); + return 0; } catalogAddresses.add (da); @@ -432,10 +436,10 @@ public class DosDisk extends AbstractFormattedDisk * There were actually three versions of DOS 3.3 that Apple released without bumping the version number: - + The first version that was released had FPBASIC and INTBASIC files that were 50 sectors in size. - + The second version of DOS 3.3, often referred to as “DOS 3.3e”, appeared at the time the Apple IIe was released. In this version, the FPBASIC and INTBASIC files were 42 sectors in size. The changes introduced at that time included code to turn @@ -443,12 +447,12 @@ public class DosDisk extends AbstractFormattedDisk command. This fix reportedly introduced an even worse bug, but as the command was not heavily used it did not make much of an impact on most programmers. The APPEND fix was applied by utilizing some formerly unused space in the DOS 3.3 code. - + The third version of DOS 3.3 appeared just before the first release of ProDOS. The only mention of this in the press was in the DOSTalk column of Softalk magazine. This final version of DOS 3.3 included a different fix for the APPEND bug, using another bit of unused space in DOS 3.3. - + With regard to the FPBASIC and INTBASIC files: There were three differences between the 50 sector and the 42 sector versions of the INTBASIC file. Firstly, the $F800-$FFFF section was removed. This area was the code for the Monitor, and with diff --git a/src/com/bytezone/diskbrowser/infocom/ObjectManager.java b/src/com/bytezone/diskbrowser/infocom/ObjectManager.java index c088185..efaddc0 100755 --- a/src/com/bytezone/diskbrowser/infocom/ObjectManager.java +++ b/src/com/bytezone/diskbrowser/infocom/ObjectManager.java @@ -54,6 +54,11 @@ class ObjectManager extends InfocomAbstractFile implements Iterable ZObject getObject (int index) { + if (index < 0 || index >= list.size ()) + { + System.out.printf ("Invalid index: %d / %d%n", index, list.size ()); + return null; + } return list.get (index); } diff --git a/src/com/bytezone/diskbrowser/prodos/FileEntry.java b/src/com/bytezone/diskbrowser/prodos/FileEntry.java index be90427..03cd7ed 100755 --- a/src/com/bytezone/diskbrowser/prodos/FileEntry.java +++ b/src/com/bytezone/diskbrowser/prodos/FileEntry.java @@ -68,7 +68,10 @@ class FileEntry extends CatalogEntry implements ProdosConstants int block = keyPtr; do { - dataBlocks.add (disk.getDiskAddress (block)); + DiskAddress diskAddress = disk.getDiskAddress (block); + if (diskAddress == null) + break; + dataBlocks.add (diskAddress); byte[] buffer = disk.readSector (block); block = HexFormatter.unsignedShort (buffer, 2); } while (block > 0);