Allow partial unpacking of corrupt NuFX disks

This commit is contained in:
Denis Molony 2021-05-13 14:56:56 +10:00
parent 90f8657722
commit a72bdff81d
7 changed files with 70 additions and 31 deletions

View File

@ -19,6 +19,7 @@ import com.bytezone.diskbrowser.nib.WozFile;
import com.bytezone.diskbrowser.utilities.Binary2;
import com.bytezone.diskbrowser.utilities.FileFormatException;
import com.bytezone.diskbrowser.utilities.NuFX;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
public class AppleDisk implements Disk
@ -42,6 +43,8 @@ public class AppleDisk implements Disk
private NuFX nuFX;
private Binary2 bin2;
private WozFile wozFile;
private PrefixDiskCopy prefixDiskCopy;
private Prefix2mg prefix2mg;
private int interleave = 0;
private static int[][] interleaveSector = //
@ -119,7 +122,7 @@ public class AppleDisk implements Disk
{
if ("2IMG".equals (prefix))
{
Prefix2mg prefix2mg = new Prefix2mg (buffer);
prefix2mg = new Prefix2mg (buffer);
if (debug)
System.out.println (prefix2mg);
@ -145,7 +148,7 @@ public class AppleDisk implements Disk
}
else if ("img".equals (suffix) || "dimg".equals (suffix))
{
PrefixDiskCopy prefixDiskCopy = new PrefixDiskCopy (buffer);
prefixDiskCopy = new PrefixDiskCopy (buffer);
blocks = prefixDiskCopy.getBlocks ();
this.sectorSize = 512;
@ -741,25 +744,20 @@ public class AppleDisk implements Disk
text.append (String.format ("Blocks............... %,d%n", blocks));
text.append (String.format ("Track size........... %,d%n", trackSize));
text.append (String.format ("Sector size.......... %d%n", sectorSize));
text.append (String.format ("Interleave........... %d", interleave));
text.append (String.format ("Interleave........... %d%n%n", interleave));
if (wozFile != null)
{
text.append ("\n\n");
text.append (wozFile);
}
else if (nuFX != null)
{
text.append ("\n\n");
text.append (nuFX);
}
else if (bin2 != null)
{
text.append ("\n\n");
text.append (bin2);
}
else if (prefixDiskCopy != null)
text.append (prefixDiskCopy);
else if (prefix2mg != null)
text.append (prefix2mg);
return text.toString ();
return Utility.rtrim (text).toString ();
}
// ---------------------------------------------------------------------------------//

View File

@ -140,8 +140,9 @@ public class DiskFactory
}
}
if ("sdk".equals (suffix) || "shk".equals (suffix) // shrinkit disk/file archive
|| "bxy".equals (suffix))
if ("sdk".equals (suffix) // NuFX disk
|| "shk".equals (suffix) // NuFX files or disk
|| "bxy".equals (suffix)) // NuFX in Binary2
{
if (debug)
System.out.println (" ** sdk/shk/bxy **");
@ -169,10 +170,11 @@ public class DiskFactory
// e.printStackTrace ();
System.out.println (e.getMessage ());
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
System.out.println (nuFX);
return null;
}
}
else if ("bny".equals (suffix))
else if ("bny".equals (suffix)) // Binary2 uncompressed files
{
if (debug)
System.out.println (" ** bny **");
@ -196,6 +198,7 @@ public class DiskFactory
// e.printStackTrace ();
System.out.println (e.getMessage ());
System.out.printf ("Error unpacking: %s%n", file.getAbsolutePath ());
System.out.println (binary2);
return null;
}
}

View File

@ -4,6 +4,7 @@ import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
// https://www.discferret.com/wiki/Apple_DiskCopy_4.2
// Apple II File Type Notes $E0/0005 (macintosh)
// -----------------------------------------------------------------------------------//
public class PrefixDiskCopy
// -----------------------------------------------------------------------------------//
@ -11,9 +12,11 @@ public class PrefixDiskCopy
private String name;
private int dataSize;
private int tagSize;
private int encoding;
private int dataChecksum;
private int tagChecksum;
private int diskFormat;
private int format;
private int id;
private int id; // should be 0x0100
// ---------------------------------------------------------------------------------//
public PrefixDiskCopy (byte[] buffer)
@ -24,7 +27,9 @@ public class PrefixDiskCopy
name = HexFormatter.getPascalString (buffer, 0);
dataSize = Utility.getLongBigEndian (buffer, 0x40);
tagSize = Utility.getLongBigEndian (buffer, 0x44);
encoding = buffer[0x50] & 0xFF;
dataChecksum = Utility.getLongBigEndian (buffer, 0x48);
tagChecksum = Utility.getLongBigEndian (buffer, 0x4C);
diskFormat = buffer[0x50] & 0xFF;
format = buffer[0x51] & 0xFF;
id = Utility.getWordBigEndian (buffer, 0x52);
}
@ -43,12 +48,14 @@ public class PrefixDiskCopy
{
StringBuilder text = new StringBuilder ();
text.append (String.format ("Name : %s%n", name));
text.append (String.format ("Data size : %08X (%<,d)%n", dataSize));
text.append (String.format ("Tag size : %08X (%<,d)%n", tagSize));
text.append (String.format ("Encoding : %02X%n", encoding));
text.append (String.format ("Format : %02X%n", format));
text.append (String.format ("ID : %04X%n", id));
text.append (String.format ("Name : %s%n", name));
text.append (String.format ("Data size : %08X (%<,d)%n", dataSize));
text.append (String.format ("Tag size : %08X (%<,d)%n", tagSize));
text.append (String.format ("Data checksum : %08X (%<,d)%n", dataChecksum));
text.append (String.format ("Tag checksum : %08X (%<,d)%n", tagChecksum));
text.append (String.format ("Disk format : %02X%n", diskFormat));
text.append (String.format ("Format byte : %02X%n", format));
text.append (String.format ("ID : %04X%n", id));
return text.toString ();
}

View File

@ -26,6 +26,7 @@ public class ProdosDisk
// -----------------------------------------------------------------------------------//
{
static final String UNDERLINE = "------------------------------------------------\n";
static final String message = "DiskBrowser";
private static final int CATALOG_SIZE = 4;
private static final int BITS_PER_BLOCK = 8 * BLOCK_SIZE;
@ -82,6 +83,7 @@ public class ProdosDisk
allocateNextBlock ();
System.arraycopy (bootSector, 0, buffer, 0, 512);
System.arraycopy (message.getBytes (), 0, buffer, 768, message.length ());
// write 4 catalog blocks
for (int i = 0, prevBlockNo = 0; i < CATALOG_SIZE; i++)

View File

@ -98,6 +98,7 @@ public class Binary2Header
{
StringBuilder text = new StringBuilder ();
text.append ("Binary2 Header\n==============\n");
text.append (String.format ("Access ................ %02X%n", accessCode));
text.append (String.format ("File type ............. %02X%n", fileType));
text.append (String.format ("Aux type .............. %04X%n", auxType));

View File

@ -38,13 +38,22 @@ class MasterHeader
// bin2 = true;
// break;
// }
if (isBin2 (buffer, ptr))
{
binary2Header = new Binary2Header (buffer, 0);
ptr += 128;
bin2 = true;
continue;
if (binary2Header.fileType == (byte) 0xE0
&& (binary2Header.auxType == 0x8000 || binary2Header.auxType == 0x8002))
{
ptr += 128;
bin2 = true;
continue;
}
else
{
System.out.printf ("Not NuFX: %02X %04X%n", binary2Header.fileType,
binary2Header.auxType);
System.out.println (binary2Header);
}
}
throw new FileFormatException ("NuFile not found");

View File

@ -155,7 +155,17 @@ public class NuFX
int auxType = record.getAuxType ();
LocalDateTime created = record.getCreated ();
LocalDateTime modified = record.getModified ();
byte[] buffer = record.getData ();
byte[] buffer;
try
{
buffer = record.getData ();
}
catch (Exception e)
{
System.out.println (e.getMessage ());
System.out.printf ("Failed to unpack: %s%n", fileName);
continue;
}
if (debug)
System.out.printf ("%3d %-35s %02X %,7d %,7d %,7d %s %s%n", ++count,
@ -175,7 +185,16 @@ public class NuFX
if (record.hasResource ())
{
buffer = record.getResourceData ();
try
{
buffer = record.getResourceData ();
}
catch (Exception e)
{
System.out.println (e.getMessage ());
System.out.printf ("Failed to unpack resource fork: %s%n", fileName);
continue;
}
disk.addResourceFork (fileEntry, buffer, buffer.length);
}
}