dmolony-DiskBrowser/src/com/bytezone/diskbrowser/disk/DiskFactory.java

747 lines
22 KiB
Java
Raw Normal View History

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;
2018-08-17 01:20:00 +00:00
import com.bytezone.diskbrowser.nib.NibFile;
import com.bytezone.diskbrowser.nib.V2dFile;
import com.bytezone.diskbrowser.nib.WozFile;
2015-06-01 09:35:51 +00:00
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 **");
2019-11-09 13:23:30 +00:00
FormattedDisk prodosDisk = checkHardDisk (file);
2016-02-24 02:13:52 +00:00
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
}
2018-07-22 11:31:07 +00:00
if (suffix.equals ("woz"))
2016-11-28 00:45:17 +00:00
{
2019-08-11 04:12:32 +00:00
if (debug)
System.out.println ("Checking woz");
2018-07-23 04:44:16 +00:00
try
{
2019-07-31 00:01:49 +00:00
WozFile wozFile = new WozFile (file);
2019-08-25 04:16:36 +00:00
2019-07-31 00:01:49 +00:00
if (wozFile.getSectorsPerTrack () == 13)
2018-08-07 08:40:06 +00:00
{
2019-07-31 00:01:49 +00:00
AppleDisk appleDisk = new AppleDisk (wozFile, 35, 13);
2018-08-07 08:40:06 +00:00
disk = checkDos (appleDisk);
return disk == null ? new DataDisk (appleDisk) : disk;
}
2019-07-30 04:57:59 +00:00
2019-07-31 00:01:49 +00:00
if (wozFile.getSectorsPerTrack () == 16)
2018-08-11 04:12:21 +00:00
{
2019-09-04 20:44:43 +00:00
if (wozFile.getDiskType () == 2)
{
if (debug)
System.out.println ("Checking woz 3.5");
2019-09-05 08:03:39 +00:00
AppleDisk disk800 = new AppleDisk (wozFile, 100 * wozFile.getSides (), 8);
2019-09-04 20:44:43 +00:00
if (ProdosDisk.isCorrectFormat (disk800))
{
if (debug)
System.out.println (" --> PRODOS hard disk");
return new ProdosDisk (disk800);
}
disk = new DataDisk (disk800);
}
else
{
AppleDisk appleDisk256 = new AppleDisk (wozFile, wozFile.getTracks (), 16);
disk = checkDos (appleDisk256);
if (disk == null)
disk = checkProdos (new AppleDisk (wozFile, 35, 8));
if (disk == null)
disk = new DataDisk (appleDisk256);
}
2018-08-11 04:12:21 +00:00
}
2019-09-04 20:44:43 +00:00
2018-07-23 04:44:16 +00:00
return disk;
}
catch (Exception e)
{
2019-03-21 23:01:08 +00:00
System.out.println (e);
2018-07-23 04:44:16 +00:00
return null;
}
2018-07-22 11:31:07 +00:00
}
2018-06-09 23:18:06 +00:00
2018-07-22 11:31:07 +00:00
if (suffix.equals ("v2d"))
{
2018-08-13 09:17:05 +00:00
V2dFile v2dDisk = new V2dFile (file);
2018-07-22 11:31:07 +00:00
AppleDisk appleDisk256 = new AppleDisk (v2dDisk, 35, 16);
disk = checkDos (appleDisk256);
2018-06-09 23:18:06 +00:00
if (disk == null)
disk = checkProdos (new AppleDisk (v2dDisk, 35, 8));
2018-07-22 11:31:07 +00:00
if (disk == null)
disk = new DataDisk (appleDisk256);
2016-11-28 06:26:26 +00:00
return disk;
2016-11-28 00:45:17 +00:00
}
2018-06-09 23:18:06 +00:00
if (suffix.equals ("nib")) // not implemented yet
2016-11-29 21:27:44 +00:00
{
2017-03-12 16:47:11 +00:00
if (debug)
System.out.println (" ** nib **");
2018-06-09 23:18:06 +00:00
2018-08-13 09:17:05 +00:00
NibFile nibDisk = new NibFile (file);
2016-11-29 21:27:44 +00:00
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);
disk2 = checkDos (appleDisk256);
if (disk2 != null)
disk = new DualDosDisk (disk, disk2);
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);
2018-12-23 01:15:51 +00:00
AppleDisk appleDisk = new AppleDisk (file, 35, 16);
disk2 = checkCPMDisk (appleDisk);
if (disk2 != null)
disk = new DualDosDisk (disk, disk2);
2015-06-01 09:35:51 +00:00
}
}
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)
{
2019-01-25 06:06:31 +00:00
e.printStackTrace ();
2015-06-01 09:35:51 +00:00
}
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;
}
2019-11-09 13:23:30 +00:00
private static FormattedDisk checkHardDisk (File file)
2015-06-01 09:35:51 +00:00
{
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
{
2019-08-25 04:16:36 +00:00
// 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);
2015-06-01 09:35:51 +00:00
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);
}
2019-11-09 13:23:30 +00:00
if (PascalDisk.isCorrectFormat (disk, debug))
{
if (debug)
System.out.println (" --> Pascal hard disk");
return new PascalDisk (disk);
}
2015-06-01 09:35:51 +00:00
}
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;
}
/*
offset | size | description
------ | ---- | -----------
+$000 | Long | The integer constant '2IMG'. This integer should be little-endian,
so on the Apple IIgs, this is equivalent to the four characters
2017-03-17 05:07:10 +00:00
'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
2017-03-17 05:07:10 +00:00
file.
+$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.
+$014 | Long | The number of 512-byte blocks in the disk image. This value should
2017-03-17 05:07:10 +00:00
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
2017-03-17 05:07:10 +00:00
the comment and creator-specific chunks.
+$01C | Long | Length of the disk data in bytes. This should be the number of
2017-03-17 05:07:10 +00:00
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
2017-03-17 05:07:10 +00:00
required (that's what the next field is for).
+$024 | Long | Length of the comment chunk. Zero if there's no comment.
+$028 | Long | Offset to the first byte of the creator-specific data chunk, or zero
2017-03-17 05:07:10 +00:00
if there is none.
+$02C | Long | Length of the creator-specific chunk; zero if there is no
2017-03-17 05:07:10 +00:00
creator-specific data.
+$030 | 16 bytes | Reserved space; this pads the header to 64 bytes. These values
2017-03-17 05:07:10 +00:00
must all be zero.
*/
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)
{
2018-07-23 07:39:25 +00:00
e.printStackTrace ();
// 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;
}
2019-07-31 00:01:49 +00:00
private static void checkMissingSectors (AppleDisk disk, WozFile wozFile)
{
}
2015-06-01 09:35:51 +00:00
}