2015-06-01 09:35:51 +00:00
|
|
|
package com.bytezone.diskbrowser.disk;
|
|
|
|
|
2016-07-30 06:12:01 +00:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
2015-06-01 09:35:51 +00:00
|
|
|
import java.nio.file.Path;
|
|
|
|
import java.nio.file.Paths;
|
2017-03-17 05:07:10 +00:00
|
|
|
import java.util.Enumeration;
|
2015-06-01 09:35:51 +00:00
|
|
|
import java.util.zip.GZIPInputStream;
|
2017-03-17 05:07:10 +00:00
|
|
|
import java.util.zip.ZipEntry;
|
|
|
|
import java.util.zip.ZipFile;
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
import com.bytezone.diskbrowser.cpm.CPMDisk;
|
|
|
|
import com.bytezone.diskbrowser.dos.DosDisk;
|
|
|
|
import com.bytezone.diskbrowser.infocom.InfocomDisk;
|
|
|
|
import com.bytezone.diskbrowser.pascal.PascalDisk;
|
|
|
|
import com.bytezone.diskbrowser.prodos.ProdosDisk;
|
2016-02-24 21:11:14 +00:00
|
|
|
import com.bytezone.diskbrowser.utilities.FileFormatException;
|
|
|
|
import com.bytezone.diskbrowser.utilities.NuFX;
|
2016-12-15 00:01:42 +00:00
|
|
|
import com.bytezone.diskbrowser.utilities.Utility;
|
2016-08-08 04:53:29 +00:00
|
|
|
import com.bytezone.diskbrowser.wizardry.Wizardry4BootDisk;
|
2015-06-01 09:35:51 +00:00
|
|
|
import com.bytezone.diskbrowser.wizardry.WizardryScenarioDisk;
|
|
|
|
|
|
|
|
public class DiskFactory
|
|
|
|
{
|
2017-03-13 07:16:20 +00:00
|
|
|
private static boolean debug = false;
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
private DiskFactory ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public static FormattedDisk createDisk (File file)
|
|
|
|
{
|
|
|
|
return createDisk (file.getAbsolutePath ());
|
|
|
|
}
|
|
|
|
|
|
|
|
public static FormattedDisk createDisk (String path)
|
|
|
|
{
|
|
|
|
if (debug)
|
2017-03-12 16:47:11 +00:00
|
|
|
System.out.println ("\nFactory : " + path);
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
File file = new File (path);
|
|
|
|
if (!file.exists ())
|
|
|
|
return null;
|
|
|
|
|
|
|
|
String suffix = path.substring (path.lastIndexOf (".") + 1).toLowerCase ();
|
|
|
|
Boolean compressed = false;
|
2016-12-15 00:01:42 +00:00
|
|
|
Path originalPath = Paths.get (path);
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2017-04-05 08:47:28 +00:00
|
|
|
if ("gz".equals (suffix))
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println (" ** gzip **");
|
2015-06-01 09:35:51 +00:00
|
|
|
try
|
|
|
|
{
|
2016-12-15 00:01:42 +00:00
|
|
|
InputStream in = new GZIPInputStream (new FileInputStream (path));
|
|
|
|
File tmp = File.createTempFile ("gzip", null);
|
2015-06-01 09:35:51 +00:00
|
|
|
FileOutputStream fos = new FileOutputStream (tmp);
|
2016-12-15 00:01:42 +00:00
|
|
|
|
|
|
|
int bytesRead;
|
|
|
|
byte[] buffer = new byte[1024];
|
|
|
|
while ((bytesRead = in.read (buffer)) > 0)
|
|
|
|
fos.write (buffer, 0, bytesRead);
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
fos.close ();
|
2016-12-15 00:01:42 +00:00
|
|
|
in.close ();
|
2015-06-01 09:35:51 +00:00
|
|
|
tmp.deleteOnExit ();
|
2016-12-15 00:01:42 +00:00
|
|
|
|
2017-03-17 05:07:10 +00:00
|
|
|
suffix = Utility.getSuffix (file.getName ()); // ignores the .gz and .zip
|
2015-06-01 09:35:51 +00:00
|
|
|
file = tmp;
|
|
|
|
compressed = true;
|
|
|
|
}
|
2016-12-15 00:01:42 +00:00
|
|
|
catch (IOException e) // can get EOFException: Unexpected end of ZLIB input stream
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
e.printStackTrace ();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2017-04-05 08:47:28 +00:00
|
|
|
else if ("zip".equals (suffix))
|
2017-03-17 05:07:10 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println (" ** zip **");
|
|
|
|
try
|
|
|
|
{
|
|
|
|
ZipFile zipFile = new ZipFile (path);
|
|
|
|
Enumeration<? extends ZipEntry> entries = zipFile.entries ();
|
|
|
|
|
|
|
|
while (entries.hasMoreElements ()) // loop until first valid name
|
|
|
|
{
|
|
|
|
ZipEntry entry = entries.nextElement ();
|
|
|
|
if (Utility.validFileType (entry.getName ()))
|
|
|
|
{
|
|
|
|
InputStream stream = zipFile.getInputStream (entry);
|
|
|
|
File tmp = File.createTempFile ("zip", null);
|
|
|
|
FileOutputStream fos = new FileOutputStream (tmp);
|
|
|
|
|
|
|
|
int bytesRead;
|
|
|
|
byte[] buffer = new byte[1024];
|
|
|
|
while ((bytesRead = stream.read (buffer)) > 0)
|
|
|
|
fos.write (buffer, 0, bytesRead);
|
|
|
|
|
|
|
|
stream.close ();
|
|
|
|
fos.close ();
|
|
|
|
tmp.deleteOnExit ();
|
|
|
|
|
|
|
|
suffix = Utility.getSuffix (file.getName ()); // ignores the .gz and .zip
|
|
|
|
file = tmp;
|
|
|
|
compressed = true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
zipFile.close ();
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
|
|
|
e.printStackTrace ();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2016-12-15 00:01:42 +00:00
|
|
|
|
|
|
|
if (suffix.equals ("sdk"))
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println (" ** sdk **");
|
2015-06-01 09:35:51 +00:00
|
|
|
try
|
|
|
|
{
|
2016-12-15 00:01:42 +00:00
|
|
|
NuFX nuFX = new NuFX (file);
|
|
|
|
File tmp = File.createTempFile ("sdk", null);
|
2015-06-01 09:35:51 +00:00
|
|
|
FileOutputStream fos = new FileOutputStream (tmp);
|
2016-12-15 00:01:42 +00:00
|
|
|
fos.write (nuFX.getBuffer ());
|
2015-06-01 09:35:51 +00:00
|
|
|
fos.close ();
|
|
|
|
tmp.deleteOnExit ();
|
|
|
|
file = tmp;
|
|
|
|
suffix = "dsk";
|
|
|
|
compressed = true;
|
|
|
|
}
|
2016-12-15 00:01:42 +00:00
|
|
|
catch (IOException e)
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
e.printStackTrace ();
|
|
|
|
return null;
|
|
|
|
}
|
2016-12-15 00:01:42 +00:00
|
|
|
catch (FileFormatException e)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
FormattedDisk disk = null;
|
|
|
|
FormattedDisk disk2 = null;
|
|
|
|
|
|
|
|
if (suffix.equals ("hdv"))
|
2016-02-24 02:13:52 +00:00
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println (" ** hdv **");
|
2016-02-24 02:13:52 +00:00
|
|
|
ProdosDisk prodosDisk = checkHardDisk (file);
|
|
|
|
if (prodosDisk != null)
|
|
|
|
return prodosDisk;
|
|
|
|
|
|
|
|
disk2 = check2mgDisk (file);
|
|
|
|
if (disk2 != null)
|
2017-03-17 05:07:10 +00:00
|
|
|
{
|
|
|
|
if (compressed)
|
|
|
|
disk2.setOriginalPath (originalPath);
|
2016-02-24 02:13:52 +00:00
|
|
|
return disk2;
|
2017-03-17 05:07:10 +00:00
|
|
|
}
|
2016-02-24 02:13:52 +00:00
|
|
|
|
|
|
|
AppleDisk appleDisk = new AppleDisk (file, (int) file.length () / 4096, 8);
|
|
|
|
return new DataDisk (appleDisk);
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
if (suffix.equals ("2mg"))
|
2016-02-24 02:13:52 +00:00
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println (" ** 2mg **");
|
2016-02-24 02:13:52 +00:00
|
|
|
disk2 = check2mgDisk (file);
|
|
|
|
if (disk2 != null)
|
2017-03-17 05:07:10 +00:00
|
|
|
{
|
|
|
|
if (compressed)
|
|
|
|
disk2.setOriginalPath (originalPath);
|
2016-02-24 02:13:52 +00:00
|
|
|
return disk2;
|
2017-03-17 05:07:10 +00:00
|
|
|
}
|
2016-02-24 02:13:52 +00:00
|
|
|
|
|
|
|
AppleDisk appleDisk = new AppleDisk (file, (int) file.length () / 4096, 8);
|
|
|
|
return new DataDisk (appleDisk);
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
if (((suffix.equals ("po") || suffix.equals ("dsk")) && file.length () > 143360))
|
|
|
|
{
|
2017-03-20 04:19:41 +00:00
|
|
|
if (file.length () < 143500) // slightly bigger than a floppy
|
|
|
|
{
|
|
|
|
System.out.println ("File length is wrong: " + file.length ());
|
|
|
|
disk = checkDos (new AppleDisk (file, 35, 16));
|
|
|
|
if (disk != null)
|
|
|
|
return disk;
|
|
|
|
}
|
|
|
|
|
2016-03-01 00:16:31 +00:00
|
|
|
if (debug)
|
2017-03-12 16:47:11 +00:00
|
|
|
System.out.println (" Checking po or dsk hard drive: " + file.length ());
|
2016-03-01 00:16:31 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
disk = checkHardDisk (file);
|
|
|
|
if (disk != null)
|
|
|
|
{
|
|
|
|
if (compressed)
|
2016-12-15 00:01:42 +00:00
|
|
|
disk.setOriginalPath (originalPath);
|
2015-06-01 09:35:51 +00:00
|
|
|
return disk;
|
|
|
|
}
|
2016-03-01 00:16:31 +00:00
|
|
|
|
|
|
|
if (debug)
|
2017-03-12 16:47:11 +00:00
|
|
|
System.out.println (" Creating a data disk from bad length");
|
2016-11-28 00:45:17 +00:00
|
|
|
|
2016-03-01 00:16:31 +00:00
|
|
|
try
|
2016-02-24 02:13:52 +00:00
|
|
|
{
|
|
|
|
AppleDisk appleDisk = new AppleDisk (file, (int) file.length () / 4096, 8);
|
2016-03-01 00:16:31 +00:00
|
|
|
if (debug)
|
2017-03-12 16:47:11 +00:00
|
|
|
System.out.println (" created data usk");
|
2016-02-24 02:13:52 +00:00
|
|
|
return new DataDisk (appleDisk);
|
|
|
|
}
|
2016-03-01 00:16:31 +00:00
|
|
|
catch (FileFormatException e)
|
|
|
|
{
|
|
|
|
if (debug)
|
2017-03-12 16:47:11 +00:00
|
|
|
System.out.println (" Creating AppleDisk failed");
|
2016-03-01 00:16:31 +00:00
|
|
|
return null;
|
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
|
2016-11-28 00:45:17 +00:00
|
|
|
if (suffix.equals ("v2d"))
|
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println (" ** v2d **");
|
2016-11-29 21:27:44 +00:00
|
|
|
V2dDisk v2dDisk = new V2dDisk (file);
|
2016-11-28 06:26:26 +00:00
|
|
|
AppleDisk appleDisk16 = new AppleDisk (v2dDisk);
|
|
|
|
disk = checkDos (appleDisk16);
|
|
|
|
return disk;
|
2016-11-28 00:45:17 +00:00
|
|
|
}
|
|
|
|
|
2016-11-29 21:27:44 +00:00
|
|
|
if (suffix.equals ("nib"))
|
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println (" ** nib **");
|
2016-11-29 21:27:44 +00:00
|
|
|
NibDisk nibDisk = new NibDisk (file);
|
|
|
|
AppleDisk appleDisk16 = new AppleDisk (nibDisk);
|
|
|
|
disk = checkDos (appleDisk16);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
long length = file.length ();
|
2016-11-28 00:45:17 +00:00
|
|
|
|
|
|
|
if (length == 116480) // 13 sector disk
|
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println (" ** 13 sector **");
|
2016-11-28 00:45:17 +00:00
|
|
|
if (!suffix.equals ("d13"))
|
|
|
|
System.out.printf ("%s should have a d13 suffix%n", file.getName ());
|
|
|
|
|
|
|
|
AppleDisk appleDisk = new AppleDisk (file, 35, 13);
|
|
|
|
disk = checkDos (appleDisk);
|
|
|
|
return disk == null ? new DataDisk (appleDisk) : disk;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (length != 143360)
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
2016-07-30 06:12:01 +00:00
|
|
|
System.out.printf ("%s: invalid file length : %,d%n", file.getName (),
|
2016-08-08 04:53:29 +00:00
|
|
|
file.length ());
|
2015-06-01 09:35:51 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2017-03-12 16:47:11 +00:00
|
|
|
AppleDisk appleDisk256 = new AppleDisk (file, 35, 16);
|
|
|
|
AppleDisk appleDisk512 = new AppleDisk (file, 35, 8);
|
2016-11-28 00:45:17 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (true)
|
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
long checksum = appleDisk256.getBootChecksum ();
|
|
|
|
|
2017-03-13 07:16:20 +00:00
|
|
|
if (checksum == 227968344L) // empty boot sector
|
|
|
|
{
|
|
|
|
// could be wizardry data, visialc data ...
|
|
|
|
if (debug)
|
|
|
|
System.out.println (" empty sector checksum : " + checksum);
|
|
|
|
}
|
|
|
|
else if (checksum == 3176296590L //
|
2017-03-12 16:47:11 +00:00
|
|
|
|| checksum == 108825457L //
|
|
|
|
|| checksum == 1439356606L //
|
|
|
|
|| checksum == 1550012074L //
|
|
|
|
|| checksum == 1614602459L //
|
|
|
|
|| checksum == 940889336L //
|
|
|
|
|| checksum == 2936955085L //
|
|
|
|
|| checksum == 1348415927L //
|
|
|
|
|| checksum == 3340889101L //
|
|
|
|
|| checksum == 18315788L //
|
|
|
|
|| checksum == 993895235L //
|
|
|
|
|| checksum == 2378342794L) // LazerPascal1.dsk
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println (" known DOS checksum : " + checksum);
|
|
|
|
disk = checkDos (appleDisk256);
|
|
|
|
disk2 = checkProdos (appleDisk512); // no need for this
|
|
|
|
if (disk2 != null && disk != null) // should be impossible
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println (" --> Dual dos/prodos 1");
|
|
|
|
System.out.println ("** impossible **");
|
2015-06-01 09:35:51 +00:00
|
|
|
disk = new DualDosDisk (disk, disk2);
|
2017-03-12 16:47:11 +00:00
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
2017-03-12 16:47:11 +00:00
|
|
|
else if (checksum == 1737448647L //
|
|
|
|
|| checksum == 170399908L //
|
|
|
|
|| checksum == 990032697) // Apple Assembly Line
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println (" known PRODOS checksum : " + checksum);
|
|
|
|
disk = checkProdos (appleDisk512);
|
|
|
|
disk2 = checkDos (appleDisk256);
|
2015-06-01 09:35:51 +00:00
|
|
|
if (disk2 != null && disk != null)
|
2017-03-12 16:47:11 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println (" --> Dual prodos/dos 2");
|
2015-06-01 09:35:51 +00:00
|
|
|
disk = new DualDosDisk (disk, disk2);
|
2017-03-12 16:47:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (checksum == 2803644711L // Apple Pascal disk 0
|
|
|
|
|| checksum == 3317783349L //
|
|
|
|
|| checksum == 1728863694L // Wizardry_I_boot.dsk
|
2017-03-13 07:16:20 +00:00
|
|
|
|| checksum == 198094178L) //
|
2017-03-12 16:47:11 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println (" known PASCAL checksum : " + checksum);
|
|
|
|
disk = checkPascalDisk (appleDisk512);
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
2017-03-12 16:47:11 +00:00
|
|
|
else if (checksum == 3028642627L //
|
|
|
|
|| checksum == 2070151659L) // Enchanter
|
2016-11-28 00:45:17 +00:00
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println (" known INFOCOM checksum : " + checksum);
|
|
|
|
disk = checkInfocomDisk (appleDisk256);
|
2016-11-28 00:45:17 +00:00
|
|
|
}
|
2017-03-12 16:47:11 +00:00
|
|
|
else if (debug)
|
|
|
|
System.out.println (" unknown checksum : " + checksum);
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-02-24 12:32:36 +00:00
|
|
|
// else if (checksum == 1212926910L || checksum == 1365043894L
|
|
|
|
// || checksum == 2128073918L)
|
|
|
|
// disk = checkCPMDisk (file);
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-02-24 09:48:09 +00:00
|
|
|
// System.out.println (checksum);
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (disk != null)
|
|
|
|
{
|
|
|
|
if (compressed)
|
2016-12-15 00:01:42 +00:00
|
|
|
disk.setOriginalPath (originalPath);
|
2015-06-01 09:35:51 +00:00
|
|
|
return disk;
|
|
|
|
}
|
|
|
|
|
|
|
|
// empty boot sector
|
|
|
|
if (checksum != 227968344L && false)
|
|
|
|
System.out.println ("Unknown checksum : " + checksum + " : " + path);
|
|
|
|
}
|
|
|
|
|
2017-03-12 16:47:11 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println (" checksum no help");
|
|
|
|
if (debug)
|
|
|
|
System.out.println (" Suffix : " + suffix);
|
|
|
|
|
2016-11-28 00:45:17 +00:00
|
|
|
if (suffix.equals ("dsk") || suffix.equals ("do"))
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
disk = checkDos (appleDisk256);
|
2015-06-01 09:35:51 +00:00
|
|
|
if (disk == null)
|
2017-03-12 16:47:11 +00:00
|
|
|
disk = checkProdos (appleDisk512);
|
2016-11-28 00:45:17 +00:00
|
|
|
else
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking DualDos disk");
|
2016-11-28 00:45:17 +00:00
|
|
|
|
2017-03-12 16:47:11 +00:00
|
|
|
disk2 = checkProdos (appleDisk512);
|
2015-06-01 09:35:51 +00:00
|
|
|
if (disk2 != null)
|
|
|
|
disk = new DualDosDisk (disk, disk2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (suffix.equals ("po"))
|
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
disk = checkProdos (appleDisk512);
|
2015-06-01 09:35:51 +00:00
|
|
|
if (disk == null)
|
2017-03-12 16:47:11 +00:00
|
|
|
disk = checkDos (appleDisk256);
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (disk == null)
|
2017-03-12 16:47:11 +00:00
|
|
|
disk = checkPascalDisk (appleDisk512);
|
2015-06-01 09:35:51 +00:00
|
|
|
|
2016-02-24 12:32:36 +00:00
|
|
|
if (disk == null)
|
2017-03-12 16:47:11 +00:00
|
|
|
disk = checkCPMDisk (appleDisk256);
|
2016-02-24 12:32:36 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (disk == null)
|
|
|
|
{
|
2017-03-12 16:47:11 +00:00
|
|
|
disk2 = checkInfocomDisk (appleDisk256);
|
2015-06-01 09:35:51 +00:00
|
|
|
if (disk2 != null)
|
|
|
|
disk = disk2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (disk == null)
|
2017-03-12 16:47:11 +00:00
|
|
|
disk = new DataDisk (appleDisk256);
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
if (debug)
|
2016-08-08 04:53:29 +00:00
|
|
|
System.out.println (
|
|
|
|
"Factory creating disk : " + disk.getDisk ().getFile ().getAbsolutePath ());
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
if (disk != null && compressed)
|
2016-12-15 00:01:42 +00:00
|
|
|
disk.setOriginalPath (originalPath);
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
return disk;
|
|
|
|
}
|
|
|
|
|
2016-11-28 00:45:17 +00:00
|
|
|
private static DosDisk checkDos (AppleDisk disk)
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking DOS disk");
|
2016-11-28 00:45:17 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
if (DosDisk.isCorrectFormat (disk))
|
2017-03-12 16:47:11 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println (" --> DOS");
|
2015-06-01 09:35:51 +00:00
|
|
|
return new DosDisk (disk);
|
2017-03-12 16:47:11 +00:00
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
if (debug)
|
2017-03-12 16:47:11 +00:00
|
|
|
System.out.println (" not a DOS disk");
|
2015-06-01 09:35:51 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-11-28 00:45:17 +00:00
|
|
|
private static ProdosDisk checkProdos (AppleDisk disk)
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking Prodos disk");
|
2016-02-28 05:41:10 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
if (ProdosDisk.isCorrectFormat (disk))
|
2017-03-12 16:47:11 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println (" --> PRODOS");
|
2015-06-01 09:35:51 +00:00
|
|
|
return new ProdosDisk (disk);
|
2017-03-12 16:47:11 +00:00
|
|
|
}
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
if (debug)
|
2017-03-12 16:47:11 +00:00
|
|
|
System.out.println (" not a Prodos disk");
|
2015-06-01 09:35:51 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static ProdosDisk checkHardDisk (File file)
|
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
{
|
|
|
|
System.out.println ("\nChecking Prodos hard disk");
|
|
|
|
System.out.printf ("Total blocks : %f%n", (float) file.length () / 512);
|
|
|
|
System.out.printf ("Total tracks : %f%n", (float) file.length () / 4096);
|
|
|
|
System.out.printf ("File length : %d%n", file.length ());
|
|
|
|
System.out.println ();
|
|
|
|
}
|
|
|
|
|
|
|
|
// assumes a sector is 512 bytes
|
|
|
|
if ((file.length () % 512) != 0)
|
|
|
|
{
|
|
|
|
if (debug)
|
2016-03-01 00:16:31 +00:00
|
|
|
System.out.printf ("file length not divisible by 512 : %,d%n%n", file.length ());
|
|
|
|
return null;
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2016-03-01 07:38:20 +00:00
|
|
|
// truncate the file if necessary
|
2015-06-01 09:35:51 +00:00
|
|
|
AppleDisk disk = new AppleDisk (file, (int) file.length () / 4096, 8);
|
|
|
|
if (ProdosDisk.isCorrectFormat (disk))
|
|
|
|
{
|
|
|
|
if (debug)
|
2017-03-12 16:47:11 +00:00
|
|
|
System.out.println (" --> PRODOS hard disk");
|
2015-06-01 09:35:51 +00:00
|
|
|
return new ProdosDisk (disk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2016-07-30 06:12:01 +00:00
|
|
|
System.out.println (e);
|
2017-03-14 04:50:23 +00:00
|
|
|
System.out.println ("Prodos hard disk had error");
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (debug)
|
2017-03-12 16:47:11 +00:00
|
|
|
System.out.println (" not a Prodos hard disk\n");
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-12-11 05:18:04 +00:00
|
|
|
/*
|
|
|
|
offset | size | description
|
|
|
|
------ | ---- | -----------
|
2017-03-17 05:07:10 +00:00
|
|
|
+$000 | Long | The integer constant '2IMG'. This integer should be little-endian,
|
|
|
|
so on the Apple IIgs, this is equivalent to the four characters
|
|
|
|
'GMI2'; in ORCA/C 2.1, you can use the integer constant '2IMG'.
|
|
|
|
+$004 | Long | A four-character tag identifying the application that created the
|
|
|
|
file.
|
2016-12-11 05:18:04 +00:00
|
|
|
+$008 | Word | The length of this header, in bytes. Should be 52.
|
|
|
|
+$00A | Word | The version number of the image file format. Should be 1.
|
|
|
|
+$00C | Long | The image format. See table below.
|
|
|
|
+$010 | Long | Flags. See table below.
|
2017-03-17 05:07:10 +00:00
|
|
|
+$014 | Long | The number of 512-byte blocks in the disk image. This value should
|
|
|
|
be zero unless the image format is 1 (ProDOS order).
|
|
|
|
+$018 | Long | Offset to the first byte of the first block of the disk in the image
|
|
|
|
file, from the beginning of the file. The disk data must come before
|
|
|
|
the comment and creator-specific chunks.
|
|
|
|
+$01C | Long | Length of the disk data in bytes. This should be the number of
|
|
|
|
blocks * 512.
|
|
|
|
+$020 | Long | Offset to the first byte of the image comment. Can be zero if
|
|
|
|
there's no comment. The comment must come after the data chunk, but
|
|
|
|
before the creator-specific chunk. The comment, if it exists, should
|
|
|
|
be raw text; no length byte or C-style null terminator byte is
|
|
|
|
required (that's what the next field is for).
|
2016-12-11 05:18:04 +00:00
|
|
|
+$024 | Long | Length of the comment chunk. Zero if there's no comment.
|
2017-03-17 05:07:10 +00:00
|
|
|
+$028 | Long | Offset to the first byte of the creator-specific data chunk, or zero
|
|
|
|
if there is none.
|
|
|
|
+$02C | Long | Length of the creator-specific chunk; zero if there is no
|
|
|
|
creator-specific data.
|
|
|
|
+$030 | 16 bytes | Reserved space; this pads the header to 64 bytes. These values
|
|
|
|
must all be zero.
|
2016-12-11 05:18:04 +00:00
|
|
|
*/
|
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
private static FormattedDisk check2mgDisk (File file)
|
|
|
|
{
|
|
|
|
if (debug)
|
2017-06-12 09:09:19 +00:00
|
|
|
System.out.println ("Checking 2mg disk");
|
2015-06-01 09:35:51 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
AppleDisk disk = new AppleDisk (file, 0, 0);
|
2017-03-17 05:07:10 +00:00
|
|
|
if (disk.getTotalBlocks () > 0 && ProdosDisk.isCorrectFormat (disk))
|
2015-06-01 09:35:51 +00:00
|
|
|
return new ProdosDisk (disk);
|
2017-06-12 09:09:19 +00:00
|
|
|
// should check for DOS, but AppleDisk assumes 2mg has 512 byte blocks
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2017-03-17 05:07:10 +00:00
|
|
|
System.out.println (e);
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Not a Prodos 2mg disk");
|
2016-02-24 02:13:52 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-11-28 00:45:17 +00:00
|
|
|
private static FormattedDisk checkPascalDisk (AppleDisk disk)
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking Pascal disk");
|
2016-08-08 04:53:29 +00:00
|
|
|
|
2016-11-28 00:45:17 +00:00
|
|
|
File file = disk.getFile ();
|
2016-08-08 04:53:29 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (!PascalDisk.isCorrectFormat (disk, debug))
|
|
|
|
return null;
|
2016-08-08 04:53:29 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println ("Pascal disk OK - Checking Wizardry disk");
|
2016-08-08 04:53:29 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (WizardryScenarioDisk.isWizardryFormat (disk, debug))
|
|
|
|
return new WizardryScenarioDisk (disk);
|
2016-08-08 04:53:29 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (debug)
|
2016-08-08 04:53:29 +00:00
|
|
|
System.out.println ("Not a Wizardry 1-3 disk");
|
|
|
|
|
2016-08-14 08:41:19 +00:00
|
|
|
// check for compressed disk
|
|
|
|
if (file.getName ().endsWith (".tmp"))
|
|
|
|
return new PascalDisk (disk); // complicated joining up compressed disks
|
2016-08-08 04:53:29 +00:00
|
|
|
|
2016-08-14 08:41:19 +00:00
|
|
|
if (Wizardry4BootDisk.isWizardryIVorV (disk, debug))
|
|
|
|
{
|
|
|
|
String fileName = file.getAbsolutePath ().toLowerCase ();
|
|
|
|
int pos = file.getAbsolutePath ().indexOf ('.');
|
|
|
|
char c = fileName.charAt (pos - 1);
|
2018-04-25 20:41:03 +00:00
|
|
|
// String suffix = fileName.substring (pos + 1);
|
2016-08-14 08:41:19 +00:00
|
|
|
int requiredDisks = c == '1' ? 6 : c == 'a' ? 10 : 0;
|
2016-08-09 04:15:44 +00:00
|
|
|
|
2016-08-14 08:41:19 +00:00
|
|
|
if (requiredDisks > 0)
|
2016-08-08 04:53:29 +00:00
|
|
|
{
|
2016-08-14 08:41:19 +00:00
|
|
|
// collect extra data disks
|
|
|
|
AppleDisk[] disks = new AppleDisk[requiredDisks];
|
|
|
|
|
|
|
|
disks[0] = new AppleDisk (file, 256, 8); // will become a PascalDisk
|
|
|
|
disks[0].setInterleave (1);
|
|
|
|
|
|
|
|
disks[1] = new AppleDisk (file, 256, 8); // will remain a DataDisk
|
|
|
|
disks[1].setInterleave (1);
|
|
|
|
|
|
|
|
if (pos > 0 && requiredDisks > 0)
|
2016-08-08 04:53:29 +00:00
|
|
|
{
|
2016-08-14 08:41:19 +00:00
|
|
|
if (collectDataDisks (file.getAbsolutePath (), pos, disks))
|
|
|
|
return new Wizardry4BootDisk (disks);
|
2016-08-08 04:53:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Not a Wizardry IV disk");
|
|
|
|
|
|
|
|
PascalDisk pascalDisk = new PascalDisk (disk);
|
|
|
|
return pascalDisk;
|
2015-06-01 09:35:51 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 08:41:19 +00:00
|
|
|
private static boolean collectDataDisks (String fileName, int dotPos, AppleDisk[] disks)
|
|
|
|
{
|
|
|
|
char c = fileName.charAt (dotPos - 1);
|
|
|
|
String suffix = fileName.substring (dotPos + 1);
|
|
|
|
|
|
|
|
for (int i = 2; i < disks.length; i++)
|
|
|
|
{
|
|
|
|
String old = new String (c + "." + suffix);
|
|
|
|
String rep = new String ((char) (c + i - 1) + "." + suffix);
|
2016-12-07 10:42:01 +00:00
|
|
|
|
2016-08-14 08:41:19 +00:00
|
|
|
File f = new File (fileName.replace (old, rep));
|
|
|
|
if (!f.exists () || !f.isFile ())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
AppleDisk dataDisk = new AppleDisk (f, 35, 8);
|
|
|
|
dataDisk.setInterleave (1);
|
|
|
|
disks[i] = dataDisk;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-11-28 00:45:17 +00:00
|
|
|
private static InfocomDisk checkInfocomDisk (AppleDisk disk)
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking Infocom disk");
|
2016-12-07 10:42:01 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (InfocomDisk.isCorrectFormat (disk))
|
2017-03-12 16:47:11 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println (" --> INFOCOM");
|
2015-06-01 09:35:51 +00:00
|
|
|
return new InfocomDisk (disk);
|
2017-03-12 16:47:11 +00:00
|
|
|
}
|
2016-12-07 10:42:01 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println ("Not an InfocomDisk disk");
|
2016-12-07 10:42:01 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2016-11-28 00:45:17 +00:00
|
|
|
private static CPMDisk checkCPMDisk (AppleDisk disk)
|
2015-06-01 09:35:51 +00:00
|
|
|
{
|
|
|
|
if (debug)
|
|
|
|
System.out.println ("Checking CPM disk");
|
2016-12-07 10:42:01 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (CPMDisk.isCorrectFormat (disk))
|
|
|
|
return new CPMDisk (disk);
|
2016-12-07 10:42:01 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
if (debug)
|
|
|
|
System.out.println ("Not a CPM disk");
|
2016-12-07 10:42:01 +00:00
|
|
|
|
2015-06-01 09:35:51 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|