diff --git a/src/com/bytezone/diskbrowser/prodos/ProdosConstants.java b/src/com/bytezone/diskbrowser/prodos/ProdosConstants.java index 806b988..f8ccc37 100755 --- a/src/com/bytezone/diskbrowser/prodos/ProdosConstants.java +++ b/src/com/bytezone/diskbrowser/prodos/ProdosConstants.java @@ -59,23 +59,23 @@ public interface ProdosConstants "FOT", "BA3", "DA3", "WPF", "SOS", "$0D", "$0E", "DIR", // "RPD", "RPI", "AFD", "AFM", "AFR", "SCL", "PFS", "$17", // "$18", "ADB", "AWP", "ASP", "$1C", "$1D", "$1E", "$1F", // - "TDM", "$21", "$22", "$23", "$24", "$25", "$26", "$27", // - "$28", "$29", "8SC", "8OB", "8IC", "8LD", "P8C", "$2F", // + "TDM", "IPS", "UPV", "$23", "$24", "$25", "$26", "$27", // + "$28", "3SD", "8SC", "8OB", "8IC", "8LD", "P8C", "$2F", // "$30", "$31", "$32", "$33", "$34", "$35", "$36", "$37", // "$38", "$39", "$3A", "$3B", "$3C", "$3D", "$3E", "$3F", // "DIC", "OCR", "FTD", "$43", "$44", "$45", "$46", "$47", // "$48", "$49", "$4A", "$4B", "$4C", "$4D", "$4E", "$4F", // "GWP", "GSS", "GDB", "DRW", "GDP", "HMD", "EDU", "STN", // "HLP", "COM", "CFG", "ANM", "MUM", "ENT", "DVU", "FIN", // - "$60", "$61", "$62", "$63", "$64", "$65", "NCF", "$67", // + "PRE", "$61", "$62", "$63", "$64", "$65", "NCF", "$67", // "$68", "$69", "$6A", "BIO", "$6C", "TDR", "PRE", "HDV", // - "$70", "$71", "$72", "$73", "$74", "$75", "$76", "$77", // - "$78", "$79", "$7A", "$7B", "$7C", "$7D", "$7E", "$7F", // + "SN2", "KMT", "DSR", "BAN", "CG7", "TNJ", "SA7", "KES", // + "JAP", "CSL", "TME", "TLB", "MR7", "MLR", "MMM", "JCP", // "GES", "GEA", "GEO", "GED", "GEF", "GEP", "GEI", "GEX", // "$88", "GEV", "$8A", "GEC", "GEK", "GEW", "$8E", "$8F", // "$90", "$91", "$92", "$93", "$94", "$95", "$96", "$97", // "$98", "$99", "$9A", "$9B", "$9C", "$9D", "$9E", "$9F", // - "WP ", "$A1", "$A2", "$A3", "$A4", "$A5", "$A6", "$A7", // + "WPJ", "$A1", "$A2", "$A3", "$A4", "$A5", "$A6", "$A7", // "$A8", "$A9", "$AA", "GSB", "TDF", "BDF", "$AE", "$AF", // "SRC", "OBJ", "LIB", "S16", "RTL", "EXE", "PIF", "TIF", // "NDA", "CDA", "TOL", "DVR", "LDF", "FST", "$BE", "DOC", // diff --git a/src/com/bytezone/diskbrowser/utilities/DateTime.java b/src/com/bytezone/diskbrowser/utilities/DateTime.java index ef842bd..fe4594d 100644 --- a/src/com/bytezone/diskbrowser/utilities/DateTime.java +++ b/src/com/bytezone/diskbrowser/utilities/DateTime.java @@ -46,6 +46,8 @@ class DateTime // ---------------------------------------------------------------------------------// { int adjustedYear = year + (year > 70 ? 1900 : 2000); + if (day < 1 || day > 31) + return null; return LocalDateTime.of (adjustedYear, month + 1, day, hour, minute); } diff --git a/src/com/bytezone/diskbrowser/utilities/LZW.java b/src/com/bytezone/diskbrowser/utilities/LZW.java index cd9bc9a..07261df 100644 --- a/src/com/bytezone/diskbrowser/utilities/LZW.java +++ b/src/com/bytezone/diskbrowser/utilities/LZW.java @@ -15,6 +15,7 @@ class LZW protected byte runLengthChar; protected int crc; protected int crcBase; + int v3eof; private int buffer; // one character buffer private int bitsLeft; // unused bits left in buffer @@ -119,14 +120,17 @@ class LZW public byte[] getData () // ---------------------------------------------------------------------------------// { - byte[] buffer = new byte[chunks.size () * TRACK_LENGTH]; + byte[] buffer = new byte[getSize ()]; int trackNumber = 0; for (byte[] track : chunks) System.arraycopy (track, 0, buffer, trackNumber++ * TRACK_LENGTH, TRACK_LENGTH); - if (crc != Utility.getCRC (buffer, crcBase)) - System.out.println ("\n*** LZW CRC mismatch ***"); + int length = v3eof != 0 ? v3eof : buffer.length; + + int calculatedCrc = Utility.getCRC (buffer, length, crcBase); + if (crc != calculatedCrc) + System.out.printf ("%n*** LZW CRC mismatch *** %04X %04X%n", crc, calculatedCrc); return buffer; } diff --git a/src/com/bytezone/diskbrowser/utilities/LZW1.java b/src/com/bytezone/diskbrowser/utilities/LZW1.java index a8d4ae6..6e1b068 100644 --- a/src/com/bytezone/diskbrowser/utilities/LZW1.java +++ b/src/com/bytezone/diskbrowser/utilities/LZW1.java @@ -75,6 +75,7 @@ class LZW1 extends LZW prev = s; } + return lzwBuffer; } diff --git a/src/com/bytezone/diskbrowser/utilities/LZW2.java b/src/com/bytezone/diskbrowser/utilities/LZW2.java index 57b4a5b..29c9e1e 100644 --- a/src/com/bytezone/diskbrowser/utilities/LZW2.java +++ b/src/com/bytezone/diskbrowser/utilities/LZW2.java @@ -11,7 +11,7 @@ class LZW2 extends LZW private int codeWord; // ---------------------------------------------------------------------------------// - public LZW2 (byte[] buffer, int crc) + public LZW2 (byte[] buffer, int crc, int eof) // ---------------------------------------------------------------------------------// { bytes = Objects.requireNonNull (buffer); @@ -19,6 +19,7 @@ class LZW2 extends LZW this.crc = crc; crcBase = 0xFFFF; codeWord = 0; + v3eof = eof; volume = buffer[0] & 0xFF; runLengthChar = (byte) (buffer[1] & 0xFF); diff --git a/src/com/bytezone/diskbrowser/utilities/MasterHeader.java b/src/com/bytezone/diskbrowser/utilities/MasterHeader.java index cb73c64..e736257 100644 --- a/src/com/bytezone/diskbrowser/utilities/MasterHeader.java +++ b/src/com/bytezone/diskbrowser/utilities/MasterHeader.java @@ -51,7 +51,7 @@ class MasterHeader byte[] crcBuffer = new byte[40]; System.arraycopy (buffer, ptr + 8, crcBuffer, 0, crcBuffer.length); - if (crc != Utility.getCRC (crcBuffer, 0)) + if (crc != Utility.getCRC (crcBuffer, crcBuffer.length, 0)) { System.out.println ("***** Master CRC mismatch *****"); throw new FileFormatException ("Master CRC failed"); diff --git a/src/com/bytezone/diskbrowser/utilities/Record.java b/src/com/bytezone/diskbrowser/utilities/Record.java index 4de4238..d64cac4 100644 --- a/src/com/bytezone/diskbrowser/utilities/Record.java +++ b/src/com/bytezone/diskbrowser/utilities/Record.java @@ -72,7 +72,7 @@ class Record byte[] crcBuffer = new byte[len + totThreads * 16]; System.arraycopy (buffer, dataPtr + 6, crcBuffer, 0, crcBuffer.length); - if (crc != Utility.getCRC (crcBuffer, 0)) + if (crc != Utility.getCRC (crcBuffer, crcBuffer.length, 0)) { System.out.println ("***** Header CRC mismatch *****"); throw new FileFormatException ("Header CRC failed"); @@ -255,9 +255,9 @@ class Record text.append (String.format ("Access ......... %s %s%n", bits, decode)); if (storType < 16) { - text.append (String.format ("File type ...... %,d %s%n", fileType, + text.append (String.format ("File type ...... %02X %s%n", fileType, ProdosConstants.fileTypes[fileType])); - text.append (String.format ("Aux type ....... %,d%n", auxType)); + text.append (String.format ("Aux type ....... %,d $%<04X%n", auxType)); text.append ( String.format ("Stor type ...... %,d %s%n", storType, storage[storType])); } diff --git a/src/com/bytezone/diskbrowser/utilities/Thread.java b/src/com/bytezone/diskbrowser/utilities/Thread.java index f115bd6..3b2998a 100644 --- a/src/com/bytezone/diskbrowser/utilities/Thread.java +++ b/src/com/bytezone/diskbrowser/utilities/Thread.java @@ -37,7 +37,7 @@ class Thread lzw = switch (header.threadFormat) { case 2 -> new LZW1 (data); - case 3 -> new LZW2 (data, header.threadCrc); + case 3 -> new LZW2 (data, header.threadCrc, header.uncompressedEOF); default -> null; // 1 = Huffman Squeeze }; diff --git a/src/com/bytezone/diskbrowser/utilities/ThreadHeader.java b/src/com/bytezone/diskbrowser/utilities/ThreadHeader.java index 095746d..650dc5a 100644 --- a/src/com/bytezone/diskbrowser/utilities/ThreadHeader.java +++ b/src/com/bytezone/diskbrowser/utilities/ThreadHeader.java @@ -17,6 +17,7 @@ class ThreadHeader final int threadClass; final int threadFormat; final int threadKind; + final int threadCrc; final int uncompressedEOF; final int compressedEOF; @@ -28,6 +29,7 @@ class ThreadHeader threadClass = Utility.getWord (buffer, offset); threadFormat = Utility.getWord (buffer, offset + 2); threadKind = Utility.getWord (buffer, offset + 4); + threadCrc = Utility.getWord (buffer, offset + 6); uncompressedEOF = Utility.getLong (buffer, offset + 8); compressedEOF = Utility.getLong (buffer, offset + 12); @@ -42,11 +44,11 @@ class ThreadHeader text.append (String.format (" threadClass ....... %d %s%n", threadClass, threadClassText[threadClass])); - text.append ( - String.format (" format ............ %d %s%n", threadFormat, formatText[threadFormat])); + text.append (String.format (" format ............ %d %s%n", threadFormat, + formatText[threadFormat])); text.append (String.format (" kind .............. %d %s%n", threadKind, threadKindText[threadClass][threadKind])); - text.append (String.format (" crc ............... %,d%n", threadCrc)); + text.append (String.format (" crc ............... %,d (%<04X)%n", threadCrc)); text.append (String.format (" uncompressedEOF ... %,d%n", uncompressedEOF)); text.append (String.format (" compressedEOF ..... %,d (%08X)", compressedEOF, compressedEOF)); diff --git a/src/com/bytezone/diskbrowser/utilities/Utility.java b/src/com/bytezone/diskbrowser/utilities/Utility.java index f45343f..3df3623 100644 --- a/src/com/bytezone/diskbrowser/utilities/Utility.java +++ b/src/com/bytezone/diskbrowser/utilities/Utility.java @@ -496,11 +496,11 @@ public class Utility } // ---------------------------------------------------------------------------------// - protected static int getCRC (final byte[] buffer, int initialValue) + protected static int getCRC (final byte[] buffer, int length, int initialValue) // ---------------------------------------------------------------------------------// { int crc = initialValue; - for (int j = 0; j < buffer.length; j++) + for (int j = 0; j < length; j++) { crc = ((crc >>> 8) | (crc << 8)) & 0xFFFF; crc ^= (buffer[j] & 0xFF);